What does the star and doublestar operator mean in a function call?
The single star *
unpacks the sequence/collection into positional arguments, so you can do this:
def sum(a, b):
return a + b
values = (1, 2)
s = sum(*values)
This will unpack the tuple so that it actually executes as:
s = sum(1, 2)
The double star **
does the same, only using a dictionary and thus named arguments:
values = { 'a': 1, 'b': 2 }
s = sum(**values)
You can also combine:
def sum(a, b, c, d):
return a + b + c + d
values1 = (1, 2)
values2 = { 'c': 10, 'd': 15 }
s = sum(*values1, **values2)
will execute as:
s = sum(1, 2, c=10, d=15)
Also see section 4.7.4 - Unpacking Argument Lists of the Python documentation.
Additionally you can define functions to take *x
and **y
arguments, this allows a function to accept any number of positional and/or named arguments that aren't specifically named in the declaration.
Example:
def sum(*values):
s = 0
for v in values:
s = s + v
return s
s = sum(1, 2, 3, 4, 5)
or with **
:
def get_a(**values):
return values['a']
s = get_a(a=1, b=2) # returns 1
this can allow you to specify a large number of optional parameters without having to declare them.
And again, you can combine:
def sum(*values, **options):
s = 0
for i in values:
s = s + i
if "neg" in options:
if options["neg"]:
s = -s
return s
s = sum(1, 2, 3, 4, 5) # returns 15
s = sum(1, 2, 3, 4, 5, neg=True) # returns -15
s = sum(1, 2, 3, 4, 5, neg=False) # returns 15
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
The *args
and **kwargs
is a common idiom to allow arbitrary number of arguments to functions as described in the section more on defining functions in the Python documentation.
The *args
will give you all function parameters as a tuple:
def foo(*args):
for a in args:
print(a)
foo(1)
# 1
foo(1,2,3)
# 1
# 2
# 3
The **kwargs
will give you all
keyword arguments except for those corresponding to a formal parameter as a dictionary.
def bar(**kwargs):
for a in kwargs:
print(a, kwargs[a])
bar(name='one', age=27)
# name one
# age 27
Both idioms can be mixed with normal arguments to allow a set of fixed and some variable arguments:
def foo(kind, *args, **kwargs):
pass
It is also possible to use this the other way around:
def foo(a, b, c):
print(a, b, c)
obj = {'b':10, 'c':'lee'}
foo(100,**obj)
# 100 10 lee
Another usage of the *l
idiom is to unpack argument lists when calling a function.
def foo(bar, lee):
print(bar, lee)
l = [1,2]
foo(*l)
# 1 2
In Python 3 it is possible to use *l
on the left side of an assignment (Extended Iterable Unpacking), though it gives a list instead of a tuple in this context:
first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]
Also Python 3 adds new semantic (refer PEP 3102):
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
pass
For example the following works in python 3 but not python 2:
>>> x = [1, 2]
>>> [*x]
[1, 2]
>>> [*x, 3, 4]
[1, 2, 3, 4]
>>> x = {1:1, 2:2}
>>> x
{1: 1, 2: 2}
>>> {**x, 3:3, 4:4}
{1: 1, 2: 2, 3: 3, 4: 4}
Such function accepts only 3 positional arguments, and everything after *
can only be passed as keyword arguments.
Note:
- A Python
dict
, semantically used for keyword argument passing, are arbitrarily ordered. However, in Python 3.6, keyword arguments are guaranteed to remember insertion order. - "The order of elements in
**kwargs
now corresponds to the order in which keyword arguments were passed to the function." - What’s New In Python 3.6 - In fact, all dicts in CPython 3.6 will remember insertion order as an implementation detail, this becomes standard in Python 3.7.
Python are multiple *(star/asterisk) allowed inside a function call
You have flake8
installed for Python 2 only, so it is analyzing your code according to Python 2's rules. See http://flake8.pycqa.org/en/latest/user/invocation.html for using flake8
to use different versions of Python you may have installed.
However, you can write your code in such a way that it will run identically under both Python 2 and Python 3.
from itertools import chain
result = [fn(*chain(args, dargs),
**dict(chain(kwargs.items(), dkwargs.items())))
for dargs in dynamic_args
for dkwargs in dynamic_kwargs]
what is the purpose of the asterisk symbol in complex(*(1,2)) in python without which it will return an error?
The *
-operator is used for argument unpacking.
You're not calling the function in the same way. Think of it this way:
complex(real=a, imaginary=b)
# vs.
complex(real=(a, b))
This is also why you see people write def fn(*args, **kwargs)
, it means that all arguments and keyword arguments will be unpacked.
what does double star followed by variable name mean in python?
It refers to all keyword arguments passed to the function that aren't in the method definition. For example:
>>> def foo(arg, **kwargs):
... print kwargs
...
>>> foo('a', b="2", c="3", bar="bar")
{'c': '3', 'b': '2', 'bar': 'bar'}
It is similar to just using one asterisk, which refers to all non-keyword arguments:
>>> def bar(arg, *args):
... print args
...
>>> bar(1, 2, 3, 'a', 'b')
(2, 3, 'a', 'b')
You can combine these(and people often do)
>>> def foobar(*args, **kwargs):
... print args
... print kwargs
...
>>> foobar(1, 2, a='3', spam='eggs')
(1, 2)
{'a': '3', 'spam': 'eggs'}
Python star symbol in a loop
It's called unpacking operator.
Here is what's written in the docs:
An asterisk
*
denotes iterable unpacking. Its operand must be an
iterable. The iterable is expanded into a sequence of items, which are
included in the new tuple, list, or set, at the site of the unpacking.
It is much like the "...
" operator from Javascript ES6. (the spread operator)
https://docs.python.org/3/reference/expressions.html#expression-lists
What do * (single star) and / (slash) do as independent parameters?
There is a new function parameter syntax /
to indicate that some function parameters must be specified positionally and cannot be used as keyword arguments.[This is new in Python 3.8
]
Documentation specifies some of the use cases/benefits of positional-only parameters
It allows pure Python functions to fully emulate behaviors of
existing C coded functions. For example, the built-inpow()
function does not accept keyword arguments:def pow(x, y, z=None, /):
"Emulate the built in pow() function"
r = x ** y
return r if z is None else r%zAnother use case is to preclude keyword arguments when the parameter
name is not helpful. For example, the builtinlen()
function has
the signaturelen(obj, /)
. This precludes awkward calls such as:len(obj='hello') # The "obj" keyword argument impairs readability
A further benefit of marking a parameter as positional-only is that
it allows the parameter name to be changed in the future without
risk of breaking client code. For example, in the statistics module,
the parameter name dist may be changed in the future. This was made
possible with the following function specification:def quantiles(dist, /, *, n=4, method='exclusive')
...
Where as *
is used to force the caller to use named arguments. This is one of the use case of named arguments.
So, given the method,
def func(self, param1, param2, /, param3, *, param4, param5):
print(param1, param2, param3, param4, param5)
It must called with
obj.func(10, 20, 30, param4=50, param5=60)
or
obj.func(10, 20, param3=30, param4=50, param5=60)
ie,
param1
,param2
must be specified positionally.param3
can be called either with positional or keyword.param4
andparam5
must be called with keyword argument.
DEMO:
>>> class MyClass(object):
... def func(self, param1, param2, /, param3, *, param4, param5):
... return param1, param2, param3, param4, param5
...
>>> obj = MyClass()
>>>
>>> assert obj.func(10, 20, 30, param4=40, param5=50), obj.func(
... 10, 20, param3=30, param4=40, param5=50
... )
Related Topics
Why Doesn't Calling a String Method Do Anything Unless Its Output Is Assigned
Error: Unable to Find Vcvarsall.Bat
How to Parse Xml and Get Instances of a Particular Node Attribute
Remap Values in Pandas Column With a Dict, Preserve Nans
How to Split a String into a List
How to Put a Variable'S Value Inside a String
How Does Python'S Super() Work With Multiple Inheritance
Why Does "Pip Install" Inside Python Raise a Syntaxerror
How to Make a Python Script Standalone Executable to Run Without Any Dependency
Running Bash Commands in Python
How to Read a Single Character from the User
How to Make a Dictionary from Separate Lists of Keys and Values
Pygame Mouse Clicking Detection
MySQL_Config Not Found When Installing MySQLdb Python Interface