.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/basics/args_and_kwargs.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_basics_args_and_kwargs.py: ====================== 1.13 args and kwargs ====================== .. important:: This lesson is still under development. .. GENERATED FROM PYTHON SOURCE LINES 11-18 ``*args`` --------- We have learned about functions that they can take one or more input arguments. If we want our function to have variable number of input arguments, one way to do this is to put asterik ``*`` before the `InputArgument` name inside ``()`` during function definition. The common practice is to use ``args`` as `InputArgument` name in this case. Thus it becomes ``*args``. This allows us to have multiple **unnamed** input arguments. .. GENERATED FROM PYTHON SOURCE LINES 21-28 .. code-block:: default def add_nums(*args): print(type(args), len(args), args) add_nums(5, 12.0) .. rst-class:: sphx-glr-script-out .. code-block:: none 2 (5, 12.0) .. GENERATED FROM PYTHON SOURCE LINES 29-33 Above ``*args`` is essentially converting all the unnamed input arguments to the function `add_nums` into tuple. Inside the above function, the unnamed input arguments 5 and 12 become `(5, 12)` tuple. We can also say that ``*args`` is packing all the unnamed input arguments into a tuple. .. GENERATED FROM PYTHON SOURCE LINES 35-39 .. code-block:: default l = [2, 3, 4] add_nums(l) .. rst-class:: sphx-glr-script-out .. code-block:: none 1 ([2, 3, 4],) .. GENERATED FROM PYTHON SOURCE LINES 40-48 Above we provided a single unnamed input argument `l` to the function `add_nums`. THerefore the length of `args` is 1. Inside the function `add_nums`, the input argument `[2,3,4]` which was a list, is taken as `([2,3,4],)` which is tuple. Since ``*args`` is converting all the unnamed input arguments to tuple, which is a sequence, so we can iterate over it as shown below. .. GENERATED FROM PYTHON SOURCE LINES 50-68 .. code-block:: default def do_add(*args): print(len(args), 'is length of args in do_add') for arg in args: print(arg) return def add_nums(*args): # we get a tuple i.e. (12,14) print(len(args), 'is length of args in add_nums') # we pass the tuple (12,14) as input argument and NOT 12,14 as two input arguments return do_add(args) add_nums(12, 14) .. rst-class:: sphx-glr-script-out .. code-block:: none 2 is length of args in add_nums 1 is length of args in do_add (12, 14) .. GENERATED FROM PYTHON SOURCE LINES 69-75 There was just one iteration in the ``for`` in `do_add` function above. This is because the input argument to `do_add` was a tuple `(12,14)` and not two input arguments `12, 14`. We have seen that ``*args`` is used to pack all the unnamed input arguments into a tuple. It can also unpack a tuple/list into individual unnamed input arguments as shown below. .. GENERATED FROM PYTHON SOURCE LINES 75-84 .. code-block:: default def do_add(*args): print(len(args), 'in do_add') return inputs = [1,2,3] do_add(*inputs) .. rst-class:: sphx-glr-script-out .. code-block:: none 3 in do_add .. GENERATED FROM PYTHON SOURCE LINES 85-86 Above, the list `inputs` is unpacked into individual input arguments `1`, `2` and `3`. .. GENERATED FROM PYTHON SOURCE LINES 86-105 .. code-block:: default def do_add(*args): # packing all unnamed input arguments into a tuple print(len(args), 'in do_add') a = 0 for arg in args: a += arg return a def add_nums(*args): # packing all unnamed input arguments into a tuple print(len(args), 'in add_nums') # we get a tuple i.e. (12,14) as input # we are again providing input as 2,3 which means we are providing two inputs return do_add(*args) # unpacking tuple into individual input arguments add_nums(12, 14) .. rst-class:: sphx-glr-script-out .. code-block:: none 2 in add_nums 2 in do_add 26 .. GENERATED FROM PYTHON SOURCE LINES 106-109 Above: `add_nums` and `do_add` are called with exactly same kind of input arguments. Note that how the packing and unpacking is being done in the above code using ``*args``. .. GENERATED FROM PYTHON SOURCE LINES 111-112 Following is an example of misplaced return statement .. GENERATED FROM PYTHON SOURCE LINES 115-132 .. code-block:: default def do_add(*args): print(len(args), 'in do_add') a = 0 for arg in args: a += arg return a def add_nums(_a, *args): print(len(args), "in add_nums") return do_add(_a, *args) # this asterik unpacks tuple args add_nums(2, 12, 14) .. rst-class:: sphx-glr-script-out .. code-block:: none 2 in add_nums 3 in do_add 2 .. GENERATED FROM PYTHON SOURCE LINES 133-140 Above, *args is packing all the unnamed input arguments (12 and 14) into a tuple. After that by the statement ``do_add(_a, *args)`` the tuple (12,14) is unpacked into individual input arguments by the asterik. The function `do_add` is called with exactly 3 input arguments. In the function `do_add`, the asterik is used to pack all the three input arguments into a tuple whose length is three. The `return` statement in `do_add` function is misplaced in the function `do_add` which is causing the function to return after first iteration of the loop. .. GENERATED FROM PYTHON SOURCE LINES 140-156 .. code-block:: default def do_add(a, *args): print(len(args), 'in do_add') for arg in args: a += arg return a def add_nums(a, *args): print(len(args), "in add_nums") return do_add(a, *args) add_nums(5, 12, 14) .. rst-class:: sphx-glr-script-out .. code-block:: none 2 in add_nums 2 in do_add 31 .. GENERATED FROM PYTHON SOURCE LINES 157-159 In the above cell `a` is the positional argument which takes 5, while while 12 and 14 are given as tuple to the function .. GENERATED FROM PYTHON SOURCE LINES 161-172 .. code-block:: default def add_nums(a, b, c): print(a, b, c) return l = [1, 5, 12] add_nums(*l) .. rst-class:: sphx-glr-script-out .. code-block:: none 1 5 12 .. GENERATED FROM PYTHON SOURCE LINES 173-178 In above code, the list `l` is unpacked into individual input arguments `1`, `5` and `12`. The function `add_nums` is called with exactly 3 input arguments. if the list `l` contains more than 3 elements, passing it will raise error because in this case the number of input arguments will be more than 3. .. GENERATED FROM PYTHON SOURCE LINES 178-183 .. code-block:: default # uncomment following line # l = [1, 5, 12, 3] # add_nums(*l) .. GENERATED FROM PYTHON SOURCE LINES 184-195 **Question:** What will be printed when we execute the following code! .. code-block:: python def foo(a, *b): print(len(b)) inputs = [1,2,3,4] foo(*inputs) .. GENERATED FROM PYTHON SOURCE LINES 197-199 *Although* we can vary the number of arguments by using `*args` but we can not know the name of input arguments. .. GENERATED FROM PYTHON SOURCE LINES 202-212 ``**kwargs`` ----------------- We saw that ``*args`` is used to pack all the unnamed input arguments into a tuple. It can also unpack a tuple/list into individual unnamed input arguments. If we want our function to have variable number of **named** input arguments, we can achieve this by putting double asterik ``**`` before the `InputArgument` name inside ``()`` during function definition. The common practice is to use ``kwargs`` as `InputArgument` name in this case. Thus it becomes ``**kwargs``. ``**kwargs`` is used to pack all the named input arguments into a dictionary. Similarly, it can also unpack a dictionary into individual named input arguments. .. GENERATED FROM PYTHON SOURCE LINES 214-222 .. code-block:: default def add_nums(**kwargs): print(type(kwargs)) add_nums(a=5, b=12) # we can not do add_nums(2,3) here .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 223-225 It is just a convention to use the word `kwargs` for keyword arguments. We can put any other name as well. For example, the above function can also be written as below. .. GENERATED FROM PYTHON SOURCE LINES 225-233 .. code-block:: default def add_nums(**dictionary): print(type(dictionary), len(dictionary)) add_nums(a=5, b=12) .. rst-class:: sphx-glr-script-out .. code-block:: none 2 .. GENERATED FROM PYTHON SOURCE LINES 234-243 .. code-block:: default def add_nums(**kwargs): print(type(kwargs)) a = 5 b = 12 dictionary = {'a': a, 'b': b} .. GENERATED FROM PYTHON SOURCE LINES 244-246 If a function has only `**kwargs` as input argument, we can not provide unnamed input arguments to the function. For example, following code will raise error. .. GENERATED FROM PYTHON SOURCE LINES 246-251 .. code-block:: default # uncomment following line to see the error # # add_nums(a,b) .. GENERATED FROM PYTHON SOURCE LINES 252-253 uncomment following line to see the error .. GENERATED FROM PYTHON SOURCE LINES 253-256 .. code-block:: default # add_nums(dictionary) .. GENERATED FROM PYTHON SOURCE LINES 257-260 `add_nums(a,b)` is invalid because we are providing two unnamed input arguments. However, `add_nums(dictionary)`` is invalid because we are providing a single unnamed input argument. .. GENERATED FROM PYTHON SOURCE LINES 260-264 .. code-block:: default add_nums(**dictionary) .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 265-277 .. code-block:: default def add_nums(**kwargs): x = kwargs['a'] y = kwargs['b'] return x + y a = 5 b = 12 dictionary = {'a': a, 'b': b} add_nums(**dictionary) .. rst-class:: sphx-glr-script-out .. code-block:: none 17 .. GENERATED FROM PYTHON SOURCE LINES 278-282 Omitting ``**`` on both sides also serves the purpose. However, if we omit ``**`` in function definition, it would mean that function requires an input argument named ``kwargs``. If we ommit ``**`` when calling the function it means that we are giving a dicionary as it is as input argument. .. GENERATED FROM PYTHON SOURCE LINES 284-298 .. code-block:: default def add_nums(kwargs): x = kwargs['a'] y = kwargs['b'] return x + y a = 5 b = 12 dictionary = {'a': a, 'b': b} add_nums(dictionary) .. rst-class:: sphx-glr-script-out .. code-block:: none 17 .. GENERATED FROM PYTHON SOURCE LINES 299-309 .. code-block:: default def add_nums(a=1, b=5): print(type(a)) return a + b d = {'a': 12, 'b': 14} add_nums(**d) .. rst-class:: sphx-glr-script-out .. code-block:: none 26 .. GENERATED FROM PYTHON SOURCE LINES 310-320 .. code-block:: default def add_nums(xx, **kwargs): x = kwargs['a'] y = kwargs['b'] return xx + x + y dictionary = {'a': 5, 'b': 12} add_nums(1, **dictionary) .. rst-class:: sphx-glr-script-out .. code-block:: none 18 .. GENERATED FROM PYTHON SOURCE LINES 321-323 ``xx`` is assigned the value of `1` when the function `add_nums` is called. We can put extra named arguments separately along with `**kwargs`. .. GENERATED FROM PYTHON SOURCE LINES 325-338 .. code-block:: default def add_nums(xx=1, **kwargs): _sum = 0.0 for key, val in kwargs.items(): _sum += val return _sum dictionary = {'a': 5, 'b': 12} add_nums(**dictionary) .. rst-class:: sphx-glr-script-out .. code-block:: none 17.0 .. GENERATED FROM PYTHON SOURCE LINES 339-340 The value of `xx` which is `1` is not added in the final answer. .. GENERATED FROM PYTHON SOURCE LINES 343-354 .. code-block:: default def add_nums(xx=1, yy=12, zz=14, **kwargs): _sum = 0.0 for key, val in kwargs.items(): _sum += val return _sum add_nums(xx=114, yy=313, zz=7, a=1, b=5, c=12, d=14) .. rst-class:: sphx-glr-script-out .. code-block:: none 32.0 .. GENERATED FROM PYTHON SOURCE LINES 355-357 now `kwargs` contained `a`, `b`, `c` and `d` only. The above code can also be written as following. .. GENERATED FROM PYTHON SOURCE LINES 360-378 .. code-block:: default def add_nums(xx=1, yy=12, zz=14, **kwargs): _sum = 0.0 for key, val in kwargs.items(): _sum += val return _sum additional_args = { "a": 1, "b": 5, "c": 12, "d": 14, } add_nums(xx=114, yy=313, zz=7, **additional_args) .. rst-class:: sphx-glr-script-out .. code-block:: none 32.0 .. GENERATED FROM PYTHON SOURCE LINES 379-380 A misplaced `return` can be a cause of many headachs, as in following case. .. GENERATED FROM PYTHON SOURCE LINES 383-405 .. code-block:: default def add_nums(xx=1, yy=12, zz=14, **kwargs): # if number of arguments are large, it is totally fine to go on # second line without any probelm _sum = 0.0 for key, val in kwargs.items(): _sum += val return _sum additional_args = { "a": 114, "b": 5, "c": 12, "d": 14, } add_nums(xx=114, yy=313, zz=7, **additional_args) .. rst-class:: sphx-glr-script-out .. code-block:: none 114.0 .. GENERATED FROM PYTHON SOURCE LINES 406-407 Above, the function `add_nums` finishs execution just after first iteration of `for loop`. .. GENERATED FROM PYTHON SOURCE LINES 410-428 .. code-block:: default def cook_lunch_with_bread(raw_food): print('prepare lunch with break') def cook_lunch_without_bread(raw_food): print('prepare lunch with {}, {} and without bread'.format(*raw_food.keys())) def lunch(**raw_food): if 'bread' in raw_food: cook_lunch_with_bread(raw_food) else: cook_lunch_without_bread(raw_food) lunch(rice='2', milk=1) .. rst-class:: sphx-glr-script-out .. code-block:: none prepare lunch with rice, milk and without bread .. GENERATED FROM PYTHON SOURCE LINES 429-432 We can predefine/fix the number of positional arguments and keyword arguments that a function must take. Following code allows only 3 positional keyword arguments and 2 keyword arguments. .. GENERATED FROM PYTHON SOURCE LINES 434-438 .. code-block:: default def add_nums(a, b, c, *, d, e): print(a, b, c) .. GENERATED FROM PYTHON SOURCE LINES 439-441 we can not do add_num(2,3,4, 12, 14), as this would mean 5 positional arguments instead of 3. .. GENERATED FROM PYTHON SOURCE LINES 441-445 .. code-block:: default add_nums(2, 3, 4, d=12, e=14) .. rst-class:: sphx-glr-script-out .. code-block:: none 2 3 4 .. GENERATED FROM PYTHON SOURCE LINES 446-449 We can make use of ``*args`` and ``**kwargs`` together in a function definition. In this case , our function can receive any number of unnamed and named input arguments. .. GENERATED FROM PYTHON SOURCE LINES 449-463 .. code-block:: default def add_nums(a, b, *args, **kwargs): _sum = a + b print(len(args), len(kwargs)) for arg in args: _sum += arg for key, val in kwargs.items(): _sum += val return _sum add_nums(2, 3) .. rst-class:: sphx-glr-script-out .. code-block:: none 0 0 5 .. GENERATED FROM PYTHON SOURCE LINES 464-467 .. code-block:: default add_nums(2, 3, 4, 5) .. rst-class:: sphx-glr-script-out .. code-block:: none 2 0 14 .. GENERATED FROM PYTHON SOURCE LINES 468-469 `4` and `5` goes to args .. GENERATED FROM PYTHON SOURCE LINES 471-474 .. code-block:: default add_nums(2, 3, 4, 5, 6, d=5, e=12) .. rst-class:: sphx-glr-script-out .. code-block:: none 3 2 37 .. GENERATED FROM PYTHON SOURCE LINES 475-476 `4`, `5`, `6` goes to args and `d` and `e` goes to kwargs .. GENERATED FROM PYTHON SOURCE LINES 479-484 We can replace the words *args* and *kwargs* with any other variable name. It is just a convention to use the word *args* for unnamed arguments and the word *kwargs* for keyword arguments. The actual packing and unpacking is done by **``*``** and **``**``** in python. For example, the above function can also be written as below .. GENERATED FROM PYTHON SOURCE LINES 484-498 .. code-block:: default def add_nums(one, five, *unnamed, **named): _sum = one + five print(len(unnamed), len(named)) for arg in unnamed: _sum += arg for key, val in named.items(): _sum += val return _sum add_nums(1, 5, 12, infallibles=14, messangers=313) .. rst-class:: sphx-glr-script-out .. code-block:: none 1 2 345 .. GENERATED FROM PYTHON SOURCE LINES 499-510 **Question**: What will be the output of following code? .. code-block:: python def foo(a = 12, b=14): b = a a += b print(a, ' ', b) foo(b=12, a=14) .. GENERATED FROM PYTHON SOURCE LINES 512-528 **Question**: Write a function named `func` which can be called as below and always returns 10. Remember, it should be the same function, but we will call it in five different ways, and it should always return 10. .. code-block:: python func(1) func(a=1, b=2) func(1, b=2) func(1,2,3,4) func(a=1, b=2, c=3, d=4) .. GENERATED FROM PYTHON SOURCE LINES 530-533 **Question**: In the above functions, what are the number of ``args`` and ``kwargs`` at each of the five calls that we have made above? .. GENERATED FROM PYTHON SOURCE LINES 535-546 **Question**: Write a function `func` which receives x and y along with ``args`` and ``kwargs`` and call this function with 5 input arguments in such a way that it returns 10. Inside the function, print the length of args and kwargs and it must be equal to 1. Remember, the as per above instructions, the signature of `func` must be as below .. code-block:: python def func(x, y, *args, **kwargs): ... .. GENERATED FROM PYTHON SOURCE LINES 548-551 **Question**: Call the above defined function (without modifying the function) so that the length of ``args`` and ``kwargs`` is greater than 1. Remember that the function must return 10. .. GENERATED FROM PYTHON SOURCE LINES 553-563 **Question**: .. code-block:: python def foo(**suggestionsf): pass foo([1,2]) # -> error Running the above code will raise error. Why? .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 0.012 seconds) .. _sphx_glr_download_auto_examples_basics_args_and_kwargs.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/AtrCheema/python-seekho/master?urlpath=lab/tree/notebooks/auto_examples/basics/args_and_kwargs.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: args_and_kwargs.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: args_and_kwargs.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_