Josh Rosenberg <[email protected]> added the comment:
scoder: dict(X, **M) is broken unless M is known to be string keyed (it used to
work, but in Python 3, it will raise a TypeError). It's part of the argument
for the additional unpacking generalizations from PEP 448; {**X, **M} does what
dict(X, **M) is trying to do, but without abusing the keyword argument passing
convention.
You also claim "It takes me a while to see the dict merge under that heap of
stars", but that's at least as much about the newness of PEP 448 (and for many
Python coders, a complete lack of familiarity with the pre-existing varargs
unpacking rules for functions) as it is about the punctuation; after all, you
clearly recognize dict(X, **M) even though it's been wrong in most contexts for
years.
In any event, I'm a strong -1 on this, for largely the same reasons as Raymond
and others:
1. It doesn't provide any new functionality, just one more way to do it; += is
satisfied by .update, + is satisfied (more generally and efficiently) by the
unpacking generalizations
2. It's needlessly confusing; addition is, for all existing types in the
standard library I can think of, lossless; the information from both sides of
the + is preserved in some form, either by addition or concatenation (and in
the concatenation case, addition is happening, just to the length of the
resulting sequence, and order is preserved). Addition for dictionaries would
introduce new rules specific to dicts that do not exist for any other type
regarding loss of values, non-additive resulting length, etc. Those rules would
likely be similar to those of dict literals and the update method, but they'd
need to be made explicit. By contrast, the PEP 448 unpacking generalization
rules followed the existing rules for dict literals; no special rules occur, it
just behaves intuitively (if you already knew the rules for dict literals
without unpacking being involved).
3. Almost any generic, duck-typing based code for which addition makes sense
will not make sense for dicts simply because it loosens the definition of
addition too much to be useful, so best case, it still raises TypeError (when
dicts added to non-dict things), worst case, it silently operates in a way that
violates the rules of both addition and concatenation rather than raising a
TypeError that the generic code could use to determine the correct thing to do.
4. The already mentioned conflict with Counter (which already has an addition
operator, with lossless semantics)
5. (Minor) It means PyDict_Type needs a non-NULL tp_as_number, so now it's
slightly slower to reject dicts as being non-numeric at the C layer
Problem #2 could be used to argue for allowing | instead of + (which would also
resolve #4, and parts of #3), since | is already used for unioning with sets,
and this operation is much closer to a union operation than addition or
concatenation. Even so, it would still be misleading; at least with sets, there
is no associated value, so it's still mostly lossless (you lose the input
lengths, but the unique input data is kept); with dicts, you'd be losing values
too.
Basically, I think the PEP 448 unpacking syntax should remain as the "one-- and
preferably only one --obvious way to" combine dictionaries as a one-liner. It's
more composable, since it allows adding arbitrary additional key/value pairs,
and more efficient, since it allows combining more than two dicts at once with
no additional temporaries: dicta + dictb + dictc requires "dictab" to be made
first, then thrown away after dictab + dictc produces dictabc, while {**dicta,
**dictb, **dictc} builds dictabc directly.
The only real argument I can see for not sticking to unpacking is that it
doesn't allow for arbitrary dict-like things to produce new dict-like things
directly; you'd have to rewrap as myspecialdict({**speciala, **specialb}). But
I don't think that's a flaw worth fixing if it means major changes to the
behavior of what I'm guessing is one of the three most commonly used types in
Python (along with int and tuple, thanks to the integration of dicts into so
many facets of the implementation).
----------
nosy: +josh.r
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue36144>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com