5

Possible Duplicate:
What does *args and **kwargs mean?

I' just reading Mining the social web and encountered a python syntax that I can't figure out:

transforms = [(', Inc.', ''), (', Inc', ''), (', LLC', ''), (', LLP', '')]

"google, Inc.".replace(*transforms[0])

But if I type

*transforms[0]

in the interpreter, it says it is invalid syntax. I googled it, but the python docu really is not up for the job.

So what does the asterisk means here please? Thank you all.

Community
  • 1
  • 1
dgg32
  • 1,409
  • 1
  • 13
  • 33
  • Note that, in my case, being forced to use the `fn(*args)` code and passing in a string variable, I had to pass in: `([myStringVariable])` – Andrew Aug 14 '17 at 18:02

4 Answers4

15

The *argument format in python means: use all elements in the sequence argument and pass them as arguments to the function.

In this specific case, that translates to:

"google, Inc.".replace(', Inc.', '')

This is easiest demonstrated:

>>> def foo(arg1, arg2):
...     print arg1, arg2
...
>>> arguments = ('spam', 'eggs')
>>> foo(*arguments)
spam, eggs

You can also use the **kw double star format to pass in keyword arguments:

>>> def foo(arg1='ham', arg2='spam'):
...     print arg1, arg2
...
>>> arguments = dict(arg2='foo', arg1='bar')
>>> foo(**arguments)
bar, foo

and you can use the same spelling in a function definition to capture arbitrary positional and keyword arguments:

>>> def foo(*args, **kw):
...     print args, kw
...
>>> foo('arg1', 'arg2', foo='bar', spam='eggs')
('arg1', 'arg2'), {'foo': 'bar', 'spam': 'eggs'}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
7

The asterisk unpacks an iterable. I think it is best explained with an example:

>>> def exampleFunction (paramA, paramB, paramC):
    print('A:', paramA)
    print('B:', paramB)
    print('C:', paramC)

>>> myTuple = ('foo', 'bar', 'baz')
>>> myTuple
('foo', 'bar', 'baz')
>>> exampleFunction(myTuple)
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    exampleFunction(myTuple)
TypeError: exampleFunction() takes exactly 3 arguments (1 given)
>>> exampleFunction(myTuple[0], myTuple[1], myTuple[2])
A: foo
B: bar
C: baz
>>> exampleFunction(*myTuple)
A: foo
B: bar
C: baz

As you can see, we defined a function that takes three arguments and a tuple with three elements. Now if we want to use the values from the tuple directly, we cannot just pass the tuple and have it working. We could pass each element separately but that is just very verbose. What we do instead is use the asterisk to unpack the tuple and essentially use the elements from the tuple as arguments.

There is a second usage for the unpacking functionality when working with a unknown number of parameters:

>>> def example2 (*params):
    for param in params:
        print(param)

>>> example2('foo')
foo
>>> example2('foo', 'bar')
foo
bar
>>> example2(*myTuple)
foo
bar
baz

The asterisk allows us here to define a parameter that takes all the remaining values that were passed and packs it into an iterable, so we can iterate it.

poke
  • 369,085
  • 72
  • 557
  • 602
  • Not just a tuple or a list - any iterable. – lvc Sep 02 '12 at 12:56
  • I don't understand why it doesn't work everywhere in the grammar. eg `l = [1, *[2, 3], 4]` should work and give me `l == [1, 2, 3, 4]` but it turns into a syntax error. because this unpacking grammar context is actually only enabled in function arguments it seems. why the heck – v.oddou Jan 14 '15 at 09:04
3

It turns the tuple passed into a list of arguments. So

"google, Inc.".replace(*transforms[0])

becomes

"google, Inc.".replace(', Inc.', '')

This way you can programatically construct the list of arguments that are being passed (with variable length being a key advantage).

bchurchill
  • 1,410
  • 8
  • 23
0

Check section 4.7.4 of the Python tutorial: http://docs.python.org/tutorial/controlflow.html#more-on-defining-functions

But if I type

*transforms[0]
in the interpreter, it says it is invalid syntax.

The * in front of transforms[0] only has meaning in a function call.

An alternative way of making this call with the data in the first tuple in the list is:

"Google, Inc.".replace(transforms[0][0],transforms[0][1])

Scooter
  • 6,802
  • 8
  • 41
  • 64