The refutations in this thread make no sense to me whatsoever. Can someone break it down? Make analogies? Why is this an "abusive hack"?
Asked
Active
Viewed 84 times
-2
-
1Please elaborate, and quote the parts you don't understand. For instance, this seems clear to me: "Also, this fails in Python 3 when keys are not strings." And Guido's statement: "I am fine with declaring `dict({}, **{1:3})` illegal, since after all it is abuse of the `**` mechanism." – John Kugelman Apr 27 '16 at 01:43
-
It may fail in Python 3, so it should be discouraged and it is not as readable as other alternatives. Which part is not clear? – Cyb3rFly3r Apr 27 '16 at 01:45
-
Guido doesn't like it, and it makes your code non-portable. If you don't care about either of those, go crazy? There's no objective way to answer this question, you're essentially asking for our opinions, which is off-topic here. – roippi Apr 27 '16 at 01:45
-
Also, questions that can't be answered without incorporating content by reference are incomplete by nature. Enough content to make a question answerable needs to be included in the question itself, which is to say that the most relevant parts of that thread should be included in the question. – Charles Duffy Apr 27 '16 at 01:51
-
(see http://meta.stackoverflow.com/questions/290431/how-to-handle-a-link-only-question -- "close it as unclear what you're asking" given a link-only question is diamond-mod advice). – Charles Duffy Apr 27 '16 at 01:53
-
Maybe explaining what the ** thing is doing? I'm not even sure how that fits into all this. From what I understand, it's like a shell expansion. It's taking each key and putting an equal sign between it and its value, and then somehow passing that into the dict constructor. I could be totally wrong, I just dont really have a clean anchor for which I can really orient this information, hence why I thought this would be a place to elucidate answers. I dont even see why the dict(,**) thing is a hack, I've just been told that this is how you x.update(y) for dictionaries, since one doesnt exist – Tom Apr 27 '16 at 02:04
-
@Tom, the `**` thing is unpacking each key/value pair into a new argument; thus, `x = dict(x, **{foo: "bar"})` is the same as `x = dict(x, foo=bar)` -- except that it's an ugly hack that only works for a subset of possible dictionaries (for instance, only ones whose keys are valid argument names); or, if it *does* work for all possible dictionaries, is depending on undefined behavior and may cease to do so in the future (since `**kwargs` is premised on the kwargs dict's keys being, well, valid keyword arguments). – Charles Duffy Apr 27 '16 at 03:19
-
...and dictionaries **absolutely do** have a `update()` method; I don't know where you get the contrary idea. – Charles Duffy Apr 27 '16 at 03:25
1 Answers
2
dict(x, **foo)
...given foo = { 'hello': 'world' }
, does the following:
dict(x, hello=world)
This is reasonably straightforward -- however, kwargs behavior is only well-defined for keys which actually could be passed as keyword arguments in (all available versions of) Python. Consider something like:
foo = { ('some', 'tuple'): 'value' }
...in which case you have a key which couldn't actually be passed as a keyword argument; to pass **foo
would be to exercise behavior which is not intuitively defined to readers, and which some versions of Python (such as Python 3) will explicitly reject.
By contrast:
x = dict(x) # create a new object
x.update(y)
...is relying only on well-defined behavior, and is portable going forward.

Charles Duffy
- 280,126
- 43
- 390
- 441