-2

The refutations in this thread make no sense to me whatsoever. Can someone break it down? Make analogies? Why is this an "abusive hack"?

Community
  • 1
  • 1
Tom
  • 919
  • 3
  • 9
  • 22
  • 1
    Please 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 Answers1

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