Inspired by Titus' blog post about Python's elusive at sign I thought I'd drop a little google egg for anyone who is learning Python and hasn't read the manual cover to cover yet (like I did ... yeah, right).
If you see a def in python with asterisks (or stars), like so:
def foo(*args, **kw):
pass
...what does this syntax do? It is buried in the Python tutorial here, under More On Defining Functions > Arbitrary Argument Lists which would only appear in a google search if you already knew what the syntax does! The first form means any arbitrary number of arguments to the function foo will be provided to you in a tuple named args. And the second form means any arbitrary number of keyword arguments will be available in the dict kw. For example:
>>> def checkout(*items, **coupons):
... print items
... print coupons
...
>>> checkout('eggs', 'cheese', 'cereal',
... cereal='10% off', cheese='buy 1 get 1')
('eggs', 'cheese', 'cereal')
{'cheese': 'buy 1 get 1', 'cereal': '10% off'}
>>>
The above section in the tutorial has the details on the order in which this is achieved.
DISCLAIMER: The author of this post does not condone lazily learning a programming language by trial and error, reading other peoples' code, or simply googling for an answer to something :)

Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by Tennessee Leeuwenburg on Wednesday Jun 20th, 2007 at 6:45p.m.
One thing which I've always been unsure of is what the * operator does in the following context
a = range(0,5)
b = range(6,10)
z = zip(a,b)
zip(*z)
This has always struck me as odd, because if I simply type
*z
in the interpreter, I get a SyntaxError.
So, what am I passing to zip?
Cheers,
-T
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by Kumar McMillan on Wednesday Jun 20th, 2007 at 9:05p.m.
Yes, it is pretty strange that you can't type *z into the interpretter and see the result, I assume it is due to python internals and how it probably collides with star for multiplication.
All you are doing by calling zip(*z) is inverting the behavior of def zip(*z): [inside of function]. Behind the scenes, python is actually calling the zip() method like so:
zip((0, 6), (1, 7), (2, 8), (3, 9))
in other words, it takes the list or iterable, z, and expands each item to be a separate argument for the function call. I dug through some code and found this as a practical example:
clauses = [ Files.c.type.id==video_type.id ]
if time is not None:
clauses.append(Files.c.modified >= time)
files = Files.select(and_(*clauses))
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by Tennessee Leeuwenburg on Wednesday Jun 20th, 2007 at 11:13p.m.
Thanks for that explanation, it makes sense. I always wondered.
-T
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by Siew Kam Onn on Thursday Jun 21st, 2007 at 2:04a.m.
Succinct.
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by Esteban on Thursday Jun 21st, 2007 at 6:39a.m.
> Yes, it is pretty strange that you can't type *z into the interpretter and see the result
And what would that result be? ;)
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by Fredrik on Thursday Jun 21st, 2007 at 7:33a.m.
> Yes, it is pretty strange that you can't type *z into the interpretter and see the result
*z is function calling syntax, not expression syntax, so you need to use it in an calling context. to see it in action, enter
def f(*args, **kw): print args, kw
and then try calling the f() function in different ways (e.g. f(*z) etc).
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by Kumar McMillan on Thursday Jun 21st, 2007 at 10:38a.m.
@Esteban :
>> Yes, it is pretty strange that you can't type *z into the interpretter and see the result
>
> And what would that result be? ;)
actually ... yeah thinking about it again it would make no sense! if z is a list then in an interactive terminal *z would be, errm, a list.
My knee-jerk response was really to the fact that to find out what zip(*z) is doing, you'd have to write your own zip method to simulate the scenario, which is slightly unintuitive to someone learning python through the terminal.
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by Albert on Tuesday Jun 26th, 2007 at 10:58a.m.
I *never* used Python, I don't have *any* book about it, but I still know what this syntax means, simply because I read the entire tutorial :p. Well, OK, the tutorial is very long, and is referred to as the manual on this page, but still.
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by Kevin on Monday Jul 9th, 2007 at 11:15a.m.
This was very helpful and I found it on google as you intended :) Just saying thanks.
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by Donn Lee on Friday Oct 24th, 2008 at 2:11a.m.
Whew! I'm glad my googling skills were good enough to find this article. Those asterisks were really bugging me to find out the meaning. Now I can sleep (and code) in peace. Thanks!
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by alundis on Tuesday Apr 21st, 2009 at 6:42p.m.
Very helpful, thank you.
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by -J on Monday Sep 13th, 2010 at 5:18p.m.
thx, very helpful indeed.
(keeping it alive)
:)
Re: What does the def-star-variable (or def-asterisk-parameter) syntax do in Python?
posted by Steve Lehar on Thursday Apr 26th, 2012 at 6:51a.m.
The core idea behind the * syntax is simple: It unwraps the outermost layer of a list and returns its contents. For example for L = ['eggs', 'cheese', 'cereal'], *L = 'eggs', 'cheese', 'cereal' , the outer [brackets] are removed, and the contents of the list are returned. This is syntactically related to the use of the * in c/c++ for dereferencing an array, i.e. for float a[10], *a is the address of its first element, treating that element as an individual item, rather than a member of the list.
For the zip example above, z = zip(a, b) gives [(0, 6), (1, 7), (2, 8), (3, 9)], so *z = (0, 6), (1, 7), (2, 8), (3, 9)
This value can't be returned at the command prompt because it is really a list of results, and thus more properly expressed as [(0, 6), (1, 7), (2, 8), (3, 9)], although as an argument to a function it just "pretends" that the elements of the list come in individually, unwrapped from the list.