What does single(not double) asterisk * means when unpacking dictionary in Python?
up vote
2
down vote
favorite
Can anyone explain the difference when unpacking the dictionary using single or double asterisk? You can mention their difference when used in function parameters, only if it is relevant here, which I don't think so.
However, there may be some relevance, because they share the same asterisk syntax.
def foo(a,b)
return a+b
tmp = {1:2,3:4}
foo(*tmp) #you get 4
foo(**tmp) #typeError: keyword should be string. Why it bothers to check the type of keyword?
Besides, why the key of dictionary is not allowed to be non-string when passed as function arguments in THIS situation? Are there any exceptions? Why they design Python in this way, is it because the compiler can't deduce the types in here or something?
Thanks!
python dictionary iterable-unpacking
add a comment |
up vote
2
down vote
favorite
Can anyone explain the difference when unpacking the dictionary using single or double asterisk? You can mention their difference when used in function parameters, only if it is relevant here, which I don't think so.
However, there may be some relevance, because they share the same asterisk syntax.
def foo(a,b)
return a+b
tmp = {1:2,3:4}
foo(*tmp) #you get 4
foo(**tmp) #typeError: keyword should be string. Why it bothers to check the type of keyword?
Besides, why the key of dictionary is not allowed to be non-string when passed as function arguments in THIS situation? Are there any exceptions? Why they design Python in this way, is it because the compiler can't deduce the types in here or something?
Thanks!
python dictionary iterable-unpacking
1
Single * unpacking grabs the keys, so it's adding 1 and 3. With double ** it's trying to callfoo(1=2, 3=4)
which doesn't make any sense. Keyword arguments must be a valid identifier.
– Alexander Reynolds
Nov 5 at 3:55
Responding to "Why it bothers to check the type of keyword?", named arguments to functions can only be strings, so trying to use non-string names guarantees the names can't match. CPython takes advantage of this by using special purpose lookup functions fordict
s guaranteed to be composed exclusively of strings (which a lot of implementation internals happen to be), so the rejecting non-strings ensures strings can go through the fastest code paths (speeding up all Python code).
– ShadowRanger
2 days ago
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
Can anyone explain the difference when unpacking the dictionary using single or double asterisk? You can mention their difference when used in function parameters, only if it is relevant here, which I don't think so.
However, there may be some relevance, because they share the same asterisk syntax.
def foo(a,b)
return a+b
tmp = {1:2,3:4}
foo(*tmp) #you get 4
foo(**tmp) #typeError: keyword should be string. Why it bothers to check the type of keyword?
Besides, why the key of dictionary is not allowed to be non-string when passed as function arguments in THIS situation? Are there any exceptions? Why they design Python in this way, is it because the compiler can't deduce the types in here or something?
Thanks!
python dictionary iterable-unpacking
Can anyone explain the difference when unpacking the dictionary using single or double asterisk? You can mention their difference when used in function parameters, only if it is relevant here, which I don't think so.
However, there may be some relevance, because they share the same asterisk syntax.
def foo(a,b)
return a+b
tmp = {1:2,3:4}
foo(*tmp) #you get 4
foo(**tmp) #typeError: keyword should be string. Why it bothers to check the type of keyword?
Besides, why the key of dictionary is not allowed to be non-string when passed as function arguments in THIS situation? Are there any exceptions? Why they design Python in this way, is it because the compiler can't deduce the types in here or something?
Thanks!
python dictionary iterable-unpacking
python dictionary iterable-unpacking
asked Nov 5 at 3:45
Han XIAO
380111
380111
1
Single * unpacking grabs the keys, so it's adding 1 and 3. With double ** it's trying to callfoo(1=2, 3=4)
which doesn't make any sense. Keyword arguments must be a valid identifier.
– Alexander Reynolds
Nov 5 at 3:55
Responding to "Why it bothers to check the type of keyword?", named arguments to functions can only be strings, so trying to use non-string names guarantees the names can't match. CPython takes advantage of this by using special purpose lookup functions fordict
s guaranteed to be composed exclusively of strings (which a lot of implementation internals happen to be), so the rejecting non-strings ensures strings can go through the fastest code paths (speeding up all Python code).
– ShadowRanger
2 days ago
add a comment |
1
Single * unpacking grabs the keys, so it's adding 1 and 3. With double ** it's trying to callfoo(1=2, 3=4)
which doesn't make any sense. Keyword arguments must be a valid identifier.
– Alexander Reynolds
Nov 5 at 3:55
Responding to "Why it bothers to check the type of keyword?", named arguments to functions can only be strings, so trying to use non-string names guarantees the names can't match. CPython takes advantage of this by using special purpose lookup functions fordict
s guaranteed to be composed exclusively of strings (which a lot of implementation internals happen to be), so the rejecting non-strings ensures strings can go through the fastest code paths (speeding up all Python code).
– ShadowRanger
2 days ago
1
1
Single * unpacking grabs the keys, so it's adding 1 and 3. With double ** it's trying to call
foo(1=2, 3=4)
which doesn't make any sense. Keyword arguments must be a valid identifier.– Alexander Reynolds
Nov 5 at 3:55
Single * unpacking grabs the keys, so it's adding 1 and 3. With double ** it's trying to call
foo(1=2, 3=4)
which doesn't make any sense. Keyword arguments must be a valid identifier.– Alexander Reynolds
Nov 5 at 3:55
Responding to "Why it bothers to check the type of keyword?", named arguments to functions can only be strings, so trying to use non-string names guarantees the names can't match. CPython takes advantage of this by using special purpose lookup functions for
dict
s guaranteed to be composed exclusively of strings (which a lot of implementation internals happen to be), so the rejecting non-strings ensures strings can go through the fastest code paths (speeding up all Python code).– ShadowRanger
2 days ago
Responding to "Why it bothers to check the type of keyword?", named arguments to functions can only be strings, so trying to use non-string names guarantees the names can't match. CPython takes advantage of this by using special purpose lookup functions for
dict
s guaranteed to be composed exclusively of strings (which a lot of implementation internals happen to be), so the rejecting non-strings ensures strings can go through the fastest code paths (speeding up all Python code).– ShadowRanger
2 days ago
add a comment |
4 Answers
4
active
oldest
votes
up vote
3
down vote
accepted
When dictionaries are iterated as lists the iteration takes the keys of it, for example
for key in tmp:
print(key)
is the same as
for key in tmp.keys():
print(key)
in this case, unpacking as *tmp
is equivalent to *tmp.keys()
, ignoring the values. If you want to use the values you can use *tmp.values()
.
Double asterisk is used for when you define a function with keyword parameters such as
def foo(a, b):
or
def foo(**kwargs):
here you can store the parameters in a dictionary and pass it as **tmp
. In the first case keys must be strings with the names of the parameter defined in the function firm. And in the second case you can work with kwargs
as a dictionary inside the function.
1
It would probably be helpful to link to the docs on expressions where both of these are formally explained. ("If the syntax *expression appears in the function call, expression must evaluate to an iterable.")
– Brad Solomon
Nov 5 at 4:07
2
Not a bad response but I want to poke to improve your answer (esp. since this topic is actually annoyingly complex). You can require keyword arguments without setting defaults, called keyword-only args. Also collecting keyword arguments with**kwargs
is a little bit different than they would be with kw-only args or kwargs with default values---in particular, you can send in strings that are not valid python identifiers.
– Alexander Reynolds
Nov 5 at 4:09
1
"Double asterisk is used for when you define a function with keyword parameters (with a default value)" is somewhat not precise. If I dodef add(a,b): return a+b
andtmp = {'a':1,'b':2}
and call 'add(**tmp)', I can still get the value of three. So the function parameters does not need default values?
– Han XIAO
Nov 5 at 4:09
add a comment |
up vote
2
down vote
def foo(a,b)
return a+b
tmp = {1:2,3:4}
foo(*tmp) #you get 4
foo(**tmp)
In this case:foo(*tmp)
mean foo(1, 3)
foo(**tmp)
mean foo(1=2, 3=4)
, which will raise an error since 1
can't be an argument. Arg must be strings and (thanks @ Alexander Reynolds for pointing this out) must start with underscore or alphabetical character. An argument must be a valid Python identifier. This mean you can't even do something like this:
def foo(1=2, 3=4):
<your code>
or
def foo('1'=2, '3'=4):
<your code>
See python_basic_syntax for more details.
1
You can improve your answer by linking to documentation; as it stands right now it is not quite correct (e.g., '2' is a string but is not a valid python identifier).
– Alexander Reynolds
Nov 5 at 4:05
Thanks for your comment, I've just made an edit
– enamoria
Nov 5 at 4:20
add a comment |
up vote
1
down vote
It is a Extended Iterable Unpacking.
>>> def add(a=0, b=0):
... return a + b
...
>>> d = {'a': 2, 'b': 3}
>>> add(**d)#corresponding to add(a=2,b=3)
5
For single *,
def add(a=0, b=0):
... return a + b
...
>>> d = {'a': 2, 'b': 3}
>>> add(*d)#corresponding to add(a='a',b='b')
ab
Learn more here.
Extended iterable unpacking is different from *args, **kwargs unpacking.
– Alexander Reynolds
Nov 5 at 4:01
add a comment |
up vote
0
down vote
I think the ** double asterisk in function parameter and unpacking dictionary means intuitively in this way:
#suppose you have this function
def foo(a,**b):
print(a)
for x in b:
print(x,"...",b[x])
#suppose you call this function in the following form
foo(whatever,m=1,n=2)
#the m=1 syntax actually means assign parameter by name, like foo(a = whatever, m = 1, n = 2)
#so you can also do foo(whatever,**{"m":1,"n":2})
#the reason for this syntax is you actually do
**b is m=1,n=2 #something like pattern matching mechanism
so b is {"m":1,"n":2}, note "m" and "n" are now in string form
#the function is actually this:
def foo(a,**b): # b = {"m":1,"n":2}
print(a)
for x in b: #for x in b.keys(), thanks to @vlizana answer
print(x,"...",b[x])
All the syntax make sense now. And it is the same for single asterisk. It is only worth noting that if you use single asterisk to unpack dictionary, you are actually trying to unpack it in a list way, and only key of dictionary are unpacked.
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
When dictionaries are iterated as lists the iteration takes the keys of it, for example
for key in tmp:
print(key)
is the same as
for key in tmp.keys():
print(key)
in this case, unpacking as *tmp
is equivalent to *tmp.keys()
, ignoring the values. If you want to use the values you can use *tmp.values()
.
Double asterisk is used for when you define a function with keyword parameters such as
def foo(a, b):
or
def foo(**kwargs):
here you can store the parameters in a dictionary and pass it as **tmp
. In the first case keys must be strings with the names of the parameter defined in the function firm. And in the second case you can work with kwargs
as a dictionary inside the function.
1
It would probably be helpful to link to the docs on expressions where both of these are formally explained. ("If the syntax *expression appears in the function call, expression must evaluate to an iterable.")
– Brad Solomon
Nov 5 at 4:07
2
Not a bad response but I want to poke to improve your answer (esp. since this topic is actually annoyingly complex). You can require keyword arguments without setting defaults, called keyword-only args. Also collecting keyword arguments with**kwargs
is a little bit different than they would be with kw-only args or kwargs with default values---in particular, you can send in strings that are not valid python identifiers.
– Alexander Reynolds
Nov 5 at 4:09
1
"Double asterisk is used for when you define a function with keyword parameters (with a default value)" is somewhat not precise. If I dodef add(a,b): return a+b
andtmp = {'a':1,'b':2}
and call 'add(**tmp)', I can still get the value of three. So the function parameters does not need default values?
– Han XIAO
Nov 5 at 4:09
add a comment |
up vote
3
down vote
accepted
When dictionaries are iterated as lists the iteration takes the keys of it, for example
for key in tmp:
print(key)
is the same as
for key in tmp.keys():
print(key)
in this case, unpacking as *tmp
is equivalent to *tmp.keys()
, ignoring the values. If you want to use the values you can use *tmp.values()
.
Double asterisk is used for when you define a function with keyword parameters such as
def foo(a, b):
or
def foo(**kwargs):
here you can store the parameters in a dictionary and pass it as **tmp
. In the first case keys must be strings with the names of the parameter defined in the function firm. And in the second case you can work with kwargs
as a dictionary inside the function.
1
It would probably be helpful to link to the docs on expressions where both of these are formally explained. ("If the syntax *expression appears in the function call, expression must evaluate to an iterable.")
– Brad Solomon
Nov 5 at 4:07
2
Not a bad response but I want to poke to improve your answer (esp. since this topic is actually annoyingly complex). You can require keyword arguments without setting defaults, called keyword-only args. Also collecting keyword arguments with**kwargs
is a little bit different than they would be with kw-only args or kwargs with default values---in particular, you can send in strings that are not valid python identifiers.
– Alexander Reynolds
Nov 5 at 4:09
1
"Double asterisk is used for when you define a function with keyword parameters (with a default value)" is somewhat not precise. If I dodef add(a,b): return a+b
andtmp = {'a':1,'b':2}
and call 'add(**tmp)', I can still get the value of three. So the function parameters does not need default values?
– Han XIAO
Nov 5 at 4:09
add a comment |
up vote
3
down vote
accepted
up vote
3
down vote
accepted
When dictionaries are iterated as lists the iteration takes the keys of it, for example
for key in tmp:
print(key)
is the same as
for key in tmp.keys():
print(key)
in this case, unpacking as *tmp
is equivalent to *tmp.keys()
, ignoring the values. If you want to use the values you can use *tmp.values()
.
Double asterisk is used for when you define a function with keyword parameters such as
def foo(a, b):
or
def foo(**kwargs):
here you can store the parameters in a dictionary and pass it as **tmp
. In the first case keys must be strings with the names of the parameter defined in the function firm. And in the second case you can work with kwargs
as a dictionary inside the function.
When dictionaries are iterated as lists the iteration takes the keys of it, for example
for key in tmp:
print(key)
is the same as
for key in tmp.keys():
print(key)
in this case, unpacking as *tmp
is equivalent to *tmp.keys()
, ignoring the values. If you want to use the values you can use *tmp.values()
.
Double asterisk is used for when you define a function with keyword parameters such as
def foo(a, b):
or
def foo(**kwargs):
here you can store the parameters in a dictionary and pass it as **tmp
. In the first case keys must be strings with the names of the parameter defined in the function firm. And in the second case you can work with kwargs
as a dictionary inside the function.
edited Nov 5 at 4:11
answered Nov 5 at 4:05
vlizana
239111
239111
1
It would probably be helpful to link to the docs on expressions where both of these are formally explained. ("If the syntax *expression appears in the function call, expression must evaluate to an iterable.")
– Brad Solomon
Nov 5 at 4:07
2
Not a bad response but I want to poke to improve your answer (esp. since this topic is actually annoyingly complex). You can require keyword arguments without setting defaults, called keyword-only args. Also collecting keyword arguments with**kwargs
is a little bit different than they would be with kw-only args or kwargs with default values---in particular, you can send in strings that are not valid python identifiers.
– Alexander Reynolds
Nov 5 at 4:09
1
"Double asterisk is used for when you define a function with keyword parameters (with a default value)" is somewhat not precise. If I dodef add(a,b): return a+b
andtmp = {'a':1,'b':2}
and call 'add(**tmp)', I can still get the value of three. So the function parameters does not need default values?
– Han XIAO
Nov 5 at 4:09
add a comment |
1
It would probably be helpful to link to the docs on expressions where both of these are formally explained. ("If the syntax *expression appears in the function call, expression must evaluate to an iterable.")
– Brad Solomon
Nov 5 at 4:07
2
Not a bad response but I want to poke to improve your answer (esp. since this topic is actually annoyingly complex). You can require keyword arguments without setting defaults, called keyword-only args. Also collecting keyword arguments with**kwargs
is a little bit different than they would be with kw-only args or kwargs with default values---in particular, you can send in strings that are not valid python identifiers.
– Alexander Reynolds
Nov 5 at 4:09
1
"Double asterisk is used for when you define a function with keyword parameters (with a default value)" is somewhat not precise. If I dodef add(a,b): return a+b
andtmp = {'a':1,'b':2}
and call 'add(**tmp)', I can still get the value of three. So the function parameters does not need default values?
– Han XIAO
Nov 5 at 4:09
1
1
It would probably be helpful to link to the docs on expressions where both of these are formally explained. ("If the syntax *expression appears in the function call, expression must evaluate to an iterable.")
– Brad Solomon
Nov 5 at 4:07
It would probably be helpful to link to the docs on expressions where both of these are formally explained. ("If the syntax *expression appears in the function call, expression must evaluate to an iterable.")
– Brad Solomon
Nov 5 at 4:07
2
2
Not a bad response but I want to poke to improve your answer (esp. since this topic is actually annoyingly complex). You can require keyword arguments without setting defaults, called keyword-only args. Also collecting keyword arguments with
**kwargs
is a little bit different than they would be with kw-only args or kwargs with default values---in particular, you can send in strings that are not valid python identifiers.– Alexander Reynolds
Nov 5 at 4:09
Not a bad response but I want to poke to improve your answer (esp. since this topic is actually annoyingly complex). You can require keyword arguments without setting defaults, called keyword-only args. Also collecting keyword arguments with
**kwargs
is a little bit different than they would be with kw-only args or kwargs with default values---in particular, you can send in strings that are not valid python identifiers.– Alexander Reynolds
Nov 5 at 4:09
1
1
"Double asterisk is used for when you define a function with keyword parameters (with a default value)" is somewhat not precise. If I do
def add(a,b): return a+b
and tmp = {'a':1,'b':2}
and call 'add(**tmp)', I can still get the value of three. So the function parameters does not need default values?– Han XIAO
Nov 5 at 4:09
"Double asterisk is used for when you define a function with keyword parameters (with a default value)" is somewhat not precise. If I do
def add(a,b): return a+b
and tmp = {'a':1,'b':2}
and call 'add(**tmp)', I can still get the value of three. So the function parameters does not need default values?– Han XIAO
Nov 5 at 4:09
add a comment |
up vote
2
down vote
def foo(a,b)
return a+b
tmp = {1:2,3:4}
foo(*tmp) #you get 4
foo(**tmp)
In this case:foo(*tmp)
mean foo(1, 3)
foo(**tmp)
mean foo(1=2, 3=4)
, which will raise an error since 1
can't be an argument. Arg must be strings and (thanks @ Alexander Reynolds for pointing this out) must start with underscore or alphabetical character. An argument must be a valid Python identifier. This mean you can't even do something like this:
def foo(1=2, 3=4):
<your code>
or
def foo('1'=2, '3'=4):
<your code>
See python_basic_syntax for more details.
1
You can improve your answer by linking to documentation; as it stands right now it is not quite correct (e.g., '2' is a string but is not a valid python identifier).
– Alexander Reynolds
Nov 5 at 4:05
Thanks for your comment, I've just made an edit
– enamoria
Nov 5 at 4:20
add a comment |
up vote
2
down vote
def foo(a,b)
return a+b
tmp = {1:2,3:4}
foo(*tmp) #you get 4
foo(**tmp)
In this case:foo(*tmp)
mean foo(1, 3)
foo(**tmp)
mean foo(1=2, 3=4)
, which will raise an error since 1
can't be an argument. Arg must be strings and (thanks @ Alexander Reynolds for pointing this out) must start with underscore or alphabetical character. An argument must be a valid Python identifier. This mean you can't even do something like this:
def foo(1=2, 3=4):
<your code>
or
def foo('1'=2, '3'=4):
<your code>
See python_basic_syntax for more details.
1
You can improve your answer by linking to documentation; as it stands right now it is not quite correct (e.g., '2' is a string but is not a valid python identifier).
– Alexander Reynolds
Nov 5 at 4:05
Thanks for your comment, I've just made an edit
– enamoria
Nov 5 at 4:20
add a comment |
up vote
2
down vote
up vote
2
down vote
def foo(a,b)
return a+b
tmp = {1:2,3:4}
foo(*tmp) #you get 4
foo(**tmp)
In this case:foo(*tmp)
mean foo(1, 3)
foo(**tmp)
mean foo(1=2, 3=4)
, which will raise an error since 1
can't be an argument. Arg must be strings and (thanks @ Alexander Reynolds for pointing this out) must start with underscore or alphabetical character. An argument must be a valid Python identifier. This mean you can't even do something like this:
def foo(1=2, 3=4):
<your code>
or
def foo('1'=2, '3'=4):
<your code>
See python_basic_syntax for more details.
def foo(a,b)
return a+b
tmp = {1:2,3:4}
foo(*tmp) #you get 4
foo(**tmp)
In this case:foo(*tmp)
mean foo(1, 3)
foo(**tmp)
mean foo(1=2, 3=4)
, which will raise an error since 1
can't be an argument. Arg must be strings and (thanks @ Alexander Reynolds for pointing this out) must start with underscore or alphabetical character. An argument must be a valid Python identifier. This mean you can't even do something like this:
def foo(1=2, 3=4):
<your code>
or
def foo('1'=2, '3'=4):
<your code>
See python_basic_syntax for more details.
edited Nov 5 at 4:19
answered Nov 5 at 4:00
enamoria
424210
424210
1
You can improve your answer by linking to documentation; as it stands right now it is not quite correct (e.g., '2' is a string but is not a valid python identifier).
– Alexander Reynolds
Nov 5 at 4:05
Thanks for your comment, I've just made an edit
– enamoria
Nov 5 at 4:20
add a comment |
1
You can improve your answer by linking to documentation; as it stands right now it is not quite correct (e.g., '2' is a string but is not a valid python identifier).
– Alexander Reynolds
Nov 5 at 4:05
Thanks for your comment, I've just made an edit
– enamoria
Nov 5 at 4:20
1
1
You can improve your answer by linking to documentation; as it stands right now it is not quite correct (e.g., '2' is a string but is not a valid python identifier).
– Alexander Reynolds
Nov 5 at 4:05
You can improve your answer by linking to documentation; as it stands right now it is not quite correct (e.g., '2' is a string but is not a valid python identifier).
– Alexander Reynolds
Nov 5 at 4:05
Thanks for your comment, I've just made an edit
– enamoria
Nov 5 at 4:20
Thanks for your comment, I've just made an edit
– enamoria
Nov 5 at 4:20
add a comment |
up vote
1
down vote
It is a Extended Iterable Unpacking.
>>> def add(a=0, b=0):
... return a + b
...
>>> d = {'a': 2, 'b': 3}
>>> add(**d)#corresponding to add(a=2,b=3)
5
For single *,
def add(a=0, b=0):
... return a + b
...
>>> d = {'a': 2, 'b': 3}
>>> add(*d)#corresponding to add(a='a',b='b')
ab
Learn more here.
Extended iterable unpacking is different from *args, **kwargs unpacking.
– Alexander Reynolds
Nov 5 at 4:01
add a comment |
up vote
1
down vote
It is a Extended Iterable Unpacking.
>>> def add(a=0, b=0):
... return a + b
...
>>> d = {'a': 2, 'b': 3}
>>> add(**d)#corresponding to add(a=2,b=3)
5
For single *,
def add(a=0, b=0):
... return a + b
...
>>> d = {'a': 2, 'b': 3}
>>> add(*d)#corresponding to add(a='a',b='b')
ab
Learn more here.
Extended iterable unpacking is different from *args, **kwargs unpacking.
– Alexander Reynolds
Nov 5 at 4:01
add a comment |
up vote
1
down vote
up vote
1
down vote
It is a Extended Iterable Unpacking.
>>> def add(a=0, b=0):
... return a + b
...
>>> d = {'a': 2, 'b': 3}
>>> add(**d)#corresponding to add(a=2,b=3)
5
For single *,
def add(a=0, b=0):
... return a + b
...
>>> d = {'a': 2, 'b': 3}
>>> add(*d)#corresponding to add(a='a',b='b')
ab
Learn more here.
It is a Extended Iterable Unpacking.
>>> def add(a=0, b=0):
... return a + b
...
>>> d = {'a': 2, 'b': 3}
>>> add(**d)#corresponding to add(a=2,b=3)
5
For single *,
def add(a=0, b=0):
... return a + b
...
>>> d = {'a': 2, 'b': 3}
>>> add(*d)#corresponding to add(a='a',b='b')
ab
Learn more here.
edited Nov 5 at 4:02
answered Nov 5 at 3:56
Ashutosh Chapagain
664213
664213
Extended iterable unpacking is different from *args, **kwargs unpacking.
– Alexander Reynolds
Nov 5 at 4:01
add a comment |
Extended iterable unpacking is different from *args, **kwargs unpacking.
– Alexander Reynolds
Nov 5 at 4:01
Extended iterable unpacking is different from *args, **kwargs unpacking.
– Alexander Reynolds
Nov 5 at 4:01
Extended iterable unpacking is different from *args, **kwargs unpacking.
– Alexander Reynolds
Nov 5 at 4:01
add a comment |
up vote
0
down vote
I think the ** double asterisk in function parameter and unpacking dictionary means intuitively in this way:
#suppose you have this function
def foo(a,**b):
print(a)
for x in b:
print(x,"...",b[x])
#suppose you call this function in the following form
foo(whatever,m=1,n=2)
#the m=1 syntax actually means assign parameter by name, like foo(a = whatever, m = 1, n = 2)
#so you can also do foo(whatever,**{"m":1,"n":2})
#the reason for this syntax is you actually do
**b is m=1,n=2 #something like pattern matching mechanism
so b is {"m":1,"n":2}, note "m" and "n" are now in string form
#the function is actually this:
def foo(a,**b): # b = {"m":1,"n":2}
print(a)
for x in b: #for x in b.keys(), thanks to @vlizana answer
print(x,"...",b[x])
All the syntax make sense now. And it is the same for single asterisk. It is only worth noting that if you use single asterisk to unpack dictionary, you are actually trying to unpack it in a list way, and only key of dictionary are unpacked.
add a comment |
up vote
0
down vote
I think the ** double asterisk in function parameter and unpacking dictionary means intuitively in this way:
#suppose you have this function
def foo(a,**b):
print(a)
for x in b:
print(x,"...",b[x])
#suppose you call this function in the following form
foo(whatever,m=1,n=2)
#the m=1 syntax actually means assign parameter by name, like foo(a = whatever, m = 1, n = 2)
#so you can also do foo(whatever,**{"m":1,"n":2})
#the reason for this syntax is you actually do
**b is m=1,n=2 #something like pattern matching mechanism
so b is {"m":1,"n":2}, note "m" and "n" are now in string form
#the function is actually this:
def foo(a,**b): # b = {"m":1,"n":2}
print(a)
for x in b: #for x in b.keys(), thanks to @vlizana answer
print(x,"...",b[x])
All the syntax make sense now. And it is the same for single asterisk. It is only worth noting that if you use single asterisk to unpack dictionary, you are actually trying to unpack it in a list way, and only key of dictionary are unpacked.
add a comment |
up vote
0
down vote
up vote
0
down vote
I think the ** double asterisk in function parameter and unpacking dictionary means intuitively in this way:
#suppose you have this function
def foo(a,**b):
print(a)
for x in b:
print(x,"...",b[x])
#suppose you call this function in the following form
foo(whatever,m=1,n=2)
#the m=1 syntax actually means assign parameter by name, like foo(a = whatever, m = 1, n = 2)
#so you can also do foo(whatever,**{"m":1,"n":2})
#the reason for this syntax is you actually do
**b is m=1,n=2 #something like pattern matching mechanism
so b is {"m":1,"n":2}, note "m" and "n" are now in string form
#the function is actually this:
def foo(a,**b): # b = {"m":1,"n":2}
print(a)
for x in b: #for x in b.keys(), thanks to @vlizana answer
print(x,"...",b[x])
All the syntax make sense now. And it is the same for single asterisk. It is only worth noting that if you use single asterisk to unpack dictionary, you are actually trying to unpack it in a list way, and only key of dictionary are unpacked.
I think the ** double asterisk in function parameter and unpacking dictionary means intuitively in this way:
#suppose you have this function
def foo(a,**b):
print(a)
for x in b:
print(x,"...",b[x])
#suppose you call this function in the following form
foo(whatever,m=1,n=2)
#the m=1 syntax actually means assign parameter by name, like foo(a = whatever, m = 1, n = 2)
#so you can also do foo(whatever,**{"m":1,"n":2})
#the reason for this syntax is you actually do
**b is m=1,n=2 #something like pattern matching mechanism
so b is {"m":1,"n":2}, note "m" and "n" are now in string form
#the function is actually this:
def foo(a,**b): # b = {"m":1,"n":2}
print(a)
for x in b: #for x in b.keys(), thanks to @vlizana answer
print(x,"...",b[x])
All the syntax make sense now. And it is the same for single asterisk. It is only worth noting that if you use single asterisk to unpack dictionary, you are actually trying to unpack it in a list way, and only key of dictionary are unpacked.
edited Nov 5 at 4:54
answered Nov 5 at 4:40
Han XIAO
380111
380111
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53148037%2fwhat-does-singlenot-double-asterisk-means-when-unpacking-dictionary-in-pytho%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
Single * unpacking grabs the keys, so it's adding 1 and 3. With double ** it's trying to call
foo(1=2, 3=4)
which doesn't make any sense. Keyword arguments must be a valid identifier.– Alexander Reynolds
Nov 5 at 3:55
Responding to "Why it bothers to check the type of keyword?", named arguments to functions can only be strings, so trying to use non-string names guarantees the names can't match. CPython takes advantage of this by using special purpose lookup functions for
dict
s guaranteed to be composed exclusively of strings (which a lot of implementation internals happen to be), so the rejecting non-strings ensures strings can go through the fastest code paths (speeding up all Python code).– ShadowRanger
2 days ago