20

Please see the code below:-

#!/usr/bin/python
# Filename: total.py

def total(initial=5, *numbers, **keywords):
    count = initial
    for number in numbers:
        count += number
    for key in keywords:
        count += keywords[key]
    return count

print(total(10, 1, 2, 3, vegetables=50, fruits=100))

Can someone please explain how is *numbers and **keywords picking up the arguments? A simple explaination is very much appreciayed Thanks in advance

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
rgolwalkar
  • 237
  • 1
  • 3
  • 10
  • What part of http://docs.python.org/reference/expressions.html#calls confused you? Can you be more specific about which paragraph was not complete enough? – S.Lott Nov 23 '10 at 10:57

2 Answers2

29

In your code numbers is assigned the (1,2,3) tuple. keywords is assigned a dictionary, containing vegetables and fruits.

One star (*) defines positional arguments. This means that you can receive any number of arguments. You can treat the passed arguments as a tuple.

Two stars (**) define keywords arguments.

The reference material is available here.

Examples

Python 2.x (before keyword-only arguments)

def foo(x, y, foo=None, *args): print [x, y, foo, args]

foo(1, 2, 3, 4)            --> [1, 2, 3, (4, )]  # foo == 4
foo(1, 2, 3, 4, foo=True)  --> TypeError

Python 3.x (with keyword-only arguments)

def foo(x, y, *args, foo=None): print([x, y, foo, args])

foo(1, 2, 3, 4)           --> [1, 2, None, (3, 4)]  # foo is None
foo(1, 2, 3, 4, foo=True) --> [1, 2, True, (3, 4)]

def combo(x=None, *args, y=None): ...  # 2.x and 3.x styles in one function

Although a seasoned programmer understands what happened in 2.x, it's counter-intuitive (a positional argument gets bound to foo= regardless of keyword arguments as long as there are enough positional arguments)

Python 3.x introduces more intuitive keyword-only arguments with PEP-3102 (keyword arguments after varargs can only be bound by name)

Brian McCutchon
  • 8,354
  • 3
  • 33
  • 45
kgiannakakis
  • 103,016
  • 27
  • 158
  • 194
  • Thanks - more on this - so does that mean first argument is always a list/tuple and the second as dictionary? – rgolwalkar Nov 23 '10 at 10:37
  • 1
    Hi S.Lott - i read kgiannakakis explaination and then read http://docs.python.org/py3k/tutorial/controlflow.html#keyword-arguments - it cleared my doubt - Thanks for checking – rgolwalkar Nov 23 '10 at 11:48
  • 1
    @kgiannakakis: the foo after running your Python 2.x example ought to be `3`, oughtn't it? – Treefish Zhang Jan 27 '17 at 20:07
2

Let's breakdown the function first.

This total function takes three parameters.

  1. initial=5 =>this is a keyword argument.
  2. *numbers =>this is a also known as *args. You can pass any number of arguments as you want.
  3. **keywords =>this is a keyword argument like a dictionary, each key that is associated with a given value.

==========================================

count = initial

*we know that initial is a keyword argument that contains a value of 5. So the value of 5 is now assigned to a variable called count.

for number in numbers:

*the number is a placeholder variable for numbers.

*we know that numbers is an arbitrary parameter so it can take any number of arguments or values.

*so now the number is going to contain the arguments which is passed in the numbers parameter while executing the function.

count += number

*each time it loops through the numbers arguments and adds the count to the number and returns a count

*when count is 5, it loops through the argument and adds the first instance of the argument. This will be repeated until the loop gets exhausted.

for key in keywords:

*this is tricky because this time the parameter is dictionary type which contains keys and corresponding values to that keys.

count += keywords[key]

return count

100 + 50 + (10, 1, 2, 3) => 166.

I know this answer is too big but understanding the underlying concept of each function is a core strength of a well rounded programmer.

Shiva
  • 31
  • 1