T
Tuomas
def g(*arg):
.... return arg
....
TV
.... return arg
....
TV
Tuomas said:... return arg
...
Diez said:g(*g('foo', 'bar'))
* and ** are the symetric - they capture ellipsis arguments, and they
make iterables/dicts passed as positional/named arguments.
Diez
('foo', 'bar')Tuomas said:... return arg
...
TV Use the following then:
... return arg
...
(('foo', 'bar'),)
You could write something like this:
def g(*arg):
# Detect the special case of a single tuple argument
if len(arg) == 1 and type(arg[0]) == tuple:
return arg[0]
else:
return arg
but now tuple arguments are treated differently to all other data. Why do
you think you need that?
Tuomas said:def g(*arg):
return arg
def f(*arg):
return g(arg)
How can g know if it is called directly with (('foo', 'bar'),) or via f
with ('foo', 'bar'). I coud write in f: return g(arg[0], arg[1]) if I
know the number of arguments, but what if I don't know that in design time?
Tuomas said:Tuomas said:def g(*arg):
return arg
def f(*arg):
return g(arg)
How can g know if it is called directly with (('foo', 'bar'),) or via
f with ('foo', 'bar'). I coud write in f: return g(arg[0], arg[1]) if
I know the number of arguments, but what if I don't know that in
design time?
So it seems that I would like to have an unpack operator:
def f(*arg):
return(!*arg)
TV
Stargaming said:Either you take one of the snippets here:
http://aspn.activestate.com/ASPN/search?query=flatten§ion=PYTHONCKBK&type=Subsection
or just use arg[0] clever (as mentioned a few times in this thread).
I am looking a shorter way to do the above in the case:
def g(*arg):
return arg
def f(*arg):
return g(arg)
How can g know if it is called directly with (('foo', 'bar'),) or via f
I fylly agree with tis: "Typically, the responsibility should be on theDennis said:Typically, the responsibility should be on the CALLER, not the
CALLED..
... return arg
...
... return g(*arg) #<<<<<<<< unpack tuple on call
...
('a', 1, 2)
Note how f() is calling g() using an * -- Since f() "knows" that its
arguments were "packed" it calls g() with an unpack marker. Then g()
gets the arguments via whatever scheme it was coded to use.
... return g(arg) #<<<<<<<<<< no tuple unpack
...
(('a', 1, 2),)
Did you miss the example I gave? Using "*args" on the "def"I fylly agree with tis: "Typically, the responsibility should be on the
CALLER, not the CALLED..". I just don't know how to unpack *arg for
calling g. I can get the len(arg), but how to formulate an unpacked call
g(arg[0], arg[1], ..). Building a string for eval("g(arg[0], arg[1],
..)") seems glumsy to me.
Thanks. My solution became:
... result = []
... for item in arg:
... if isinstance(item, (list, tuple)):
... result.extend(flattern(item))
... else:
... result.append(item)
... return tuple(result)
...... arg = flattern(arg)
... return arg
...... return g(arg)
...('foo', 'bar')
('foo', [1, 2, 3], None)f("foo", [1,2,3], None) # three arguments turns into five ('foo', 1, 2, 3, None)
shortf("foo", [1,2,3], None) # three arguments stays three
Dennis said:I fylly agree with tis: "Typically, the responsibility should be on the
CALLER, not the CALLED..". I just don't know how to unpack *arg for
calling g. I can get the len(arg), but how to formulate an unpacked call
g(arg[0], arg[1], ..). Building a string for eval("g(arg[0], arg[1],
..)") seems glumsy to me.
Did you miss the example I gave? Using "*args" on the "def"
essentially says "pack remaining arguments into one tuple". Using
"*args" on a CALL says "UNPACK tuple into positional arguments"
def f(*args): <<<< pack arguments into tuple
x = g(*args) >>>> unpack args tuple when calling
Steven said:Thanks. My solution became:
... result = []def flattern(arg):
... for item in arg:
... if isinstance(item, (list, tuple)):
... result.extend(flattern(item))
... else:
... result.append(item)
... return tuple(result)
...... arg = flattern(arg)def g(*arg):
... return arg
...... return g(arg)def f(*arg):
...('foo', 'bar')f('foo', 'bar')
That's the most complicated do-nothing function I've ever seen. Here is a
shorter version:
def shortf(*args):
return args
('foo', 'bar')
('foo', 'bar')
(1, 2, 3, 4)
(1, 2, 3, 4)
({}, None, 1, -1.2, 'hello world')
({}, None, 1, -1.2, 'hello world')
Actually, they aren't *quite* identical: your function rips lists apart,
which is probably not a good idea.
f("foo", [1,2,3], None) # three arguments turns into five
('foo', 1, 2, 3, None)
shortf("foo", [1,2,3], None) # three arguments stays three
('foo', [1, 2, 3], None)
I still don't understand why you are doing this. Can we have an example of
why you think you need to do this?
Tuomas said:Steven said:Thanks. My solution became:
def flattern(arg):
... result = []
... for item in arg:
... if isinstance(item, (list, tuple)):
... result.extend(flattern(item))
... else:
... result.append(item)
... return tuple(result)
...
def g(*arg):
... arg = flattern(arg)
... return arg
...
def f(*arg):
... return g(arg)
...
f('foo', 'bar')
('foo', 'bar')
That's the most complicated do-nothing function I've ever seen. Here is a
shorter version:
def shortf(*args):
return args
f('foo', 'bar')
('foo', 'bar')
shortf('foo', 'bar')
('foo', 'bar')
f(1,2,3,4)
(1, 2, 3, 4)
shortf(1,2,3,4)
(1, 2, 3, 4)
f({}, None, 1, -1.2, "hello world")
({}, None, 1, -1.2, 'hello world')
shortf({}, None, 1, -1.2, "hello world")
({}, None, 1, -1.2, 'hello world')
Actually, they aren't *quite* identical: your function rips lists apart,
which is probably not a good idea.
f("foo", [1,2,3], None) # three arguments turns into five
('foo', 1, 2, 3, None)
shortf("foo", [1,2,3], None) # three arguments stays three
('foo', [1, 2, 3], None)
I still don't understand why you are doing this. Can we have an example of
why you think you need to do this?
If i redefine the function g the difference comes visible:
.... if with_flattern: arg=flattern(arg)
.... return arg
If you read the whole chain you find out what we were talking of.
TV
Steve said:Suppose you did actually want to do this you have chosen about the worst
possible way: the use of global variables to condition function
execution is a sure way to get into trouble. Consider if somebody else
want to use your function: they also have to set a global in their
program to avoid your function raising an exception.
Fortunately Python has just the thing to make such horrors unnecessary:
the default argument value. Try something like this (untested):
def g(flattening=True, *arg):
if flattening:
arg = flatten(arg)
return arg
Obviously you could use either True or False for the default value. In
the case above the function flattens by default. You could also, if you
wished, have f() take the flattening argument, and always pass it to g().
Nothing very sophisticated here, just something to help you flex your
growing Python and programming muscles.
If you read the whole chain you find out what we were talking of.
Steven said:I had already read the whole thread, and I've read it again in case I
missed something the first time, and I still have no idea why you think
you need to do this. You explain *what* you want to do, but not *why* you
want to do it.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.