* operator--as in *args?

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Sun Mar 18 21:52:32 EDT 2007


En Sun, 18 Mar 2007 22:21:41 -0300, Alex Martelli <aleax at mac.com> escribió:

> 7stud <bbxx789_05ss at yahoo.com> wrote:
>
>> I played around with it a little bit, and it appears the * operator
>> unpacks a list, tuple, or dictionary so that each element of the
>> container gets assigned to a different parameter variable.  Although
>> with a dictionary, only the keys appear to be assigned to the
>> parameter variables, e.g.:
>>
>> def g(a,b,c):
>>         print a, b, c
>>
>> dict = {"x":10, "y":20, "z":30}
>> g(*dict)
>>
>> Is that right?
>
> As far as it goes, yes.  More generally, with any iterable x, the *x
> construct in function call will pass as positional arguments exactly
> those items which (e.g.) would be printed by the loop:
>     for item in x: print x
>
> [[this applies to iterators, generators, genexps, and any other iterable
> you may care to name -- not just lists, tuples, dicts, but also sets,
> files open for reading [the items are the lines], etc, etc]].

But the language reference says "sequence", not "iterable"  
(http://docs.python.org/ref/calls.html) and a dictionary is not a  
sequence. With Python 2.1 it was an error; it is not with 2.3 (I can't  
test with 2.2 right now)

Python 2.1.3 (#35, Apr  8 2002, 17:47:50) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
>>> def f(*args, **kw):
...   print "args",args
...   print "kw",kw
...
>>> d = {"a":1, "b":2, "c":3}
>>> f(**d)
args ()
kw {'b': 2, 'c': 3, 'a': 1}
>>> f(*d)
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
TypeError: f() argument after * must be a sequence

If allowing f(*d) is actually the intended behavior, maybe the wording in  
the reference should be updated. If not, f(*d) should still raise an error.

-- 
Gabriel Genellina




More information about the Python-list mailing list