21 ms·
Dictionary union (PEP 584) is merged
- kam 7y agoThe PEP document describing the feature: https://www.python.org/dev/peps/pep-0584/ https://www.python.org/dev/peps/pep-0584/
- pansa2 7y ago> > Dict union will violate the Only One Way koan from the Zen. > There is no such koan. "Only One Way" is a calumny about Python originating long ago from the Perl community.
- wwright 7y agoFor what it is worth, from https://www.python.org/dev/peps/pep-0020/ https://www.python.org/dev/peps/pep-0020/: > There should be one-- and preferably only one --obvious way to do it. Personally, I’ve always thought that Python missed its Zen, both here and on “explicit is better than implicit.”
- ehsankia 7y agoThat ship had long sailed with string formatting anyways.
- saagarjha 7y agoIt sailed long before that.
- mokus 7y agoIt sailed with Turing completeness! At least, the popular interpretation of the phrase that ignores the word “obvious” did.
- orf 7y agoIt sailed when they added the for loop - everyone was happy using while loops, things worked and it was simple. Now there are TWO ways of calling a block of code repeatedly based? How confusing for new users. Python really went downhill since then.
- anon102010 7y agoI think go dropped one of these (for vs while) to keep to just one approach on loops so python providing lots of ways to do same thing is something other languages targeting entry level folks are seeking to avoid
- pwdisswordfish2 7y agoAh, so that's what the migration to Python 3 was all about!
- eesmith 7y agoGo back to 1.0 and we still had two ways to write strings ("abc" and 'abc'), and two ways to write not equal ("!=" and "<>"). The last died with 3.0. But my point is that the Zen of Python must be seen as a post hoc description overlaid onto whatever the actual Python philosophy is. Aligned, certainly, but at times only roughly aligned. So I don't see it as having sailed (with string formatting, or other specific even) but never having been there in the first place. More like, sailing in the same waters.
- orf 7y agoF-strings are the one obvious way to do string formatting. There may be other ways, for legacy backwards compatibility reasons, but f-strings are the way to do string formatting.
- kzrdude 7y agoI think you are right. Just left a string of legacy (%-formatting) and dead end (.format()) solutions on the way there.
- cochne 7y agoI disagree. In logging for example, ‘%s’ with the value as an argument to the logger is preferred because the formatting can be ignored if the log level is not sufficient to print.
- orf 7y agoLog formatting is a different problem than string formatting. With log formatting you pass the formatting arguments as function parameters, which is completely different from any other way you format strings.
- AlexandrB 7y agoI think you're getting downvoted because logging is basically doing: def log(fmt, *args): print(fmt % args) Hardly a huge change.
- heavenlyblue 7y agoExcept log formatting isn’t the same as actually executing the expression passed to the logging function.
- mixmastamyk 7y agoYes, unless a template is needed later. That's why the others continue to exist.
- AlexandrB 7y ago
- seemslegit 7y agoI wouldn't have thought about dict unpacking as a solution either but once suggested it seems satisfactory and I don't see how adding a new operator is more discoverable or natural than just putting this method in a more prominent place in the documentation.
- Znafon 7y agoGuido himself said he had forgotten about this trick and since it's syntactic sugar, it does not respect dict subclasses or other mappings.
- seemslegit 7y agoimo defaultdict(callback,{**a,**b}) is more readable than a | b without knowing that a or b are defaultdicts and having to reason about which default callback will be used
- anonymoushn 7y agoNote that a | b is already a disaster if you try to use subclasses of set. In python 2.7, iirc it would return a set of a's type but without calling the constructor. In python 3 it seems to return a set (not the type of a or the type of b).
- CameronNemo 7y agoNot sure about the set operator, but this operator is meant to handle subclasses better than the status quo.
- mdrachuk 7y agoWow, one more point for python 3. Just override ‘__and__’ in your whatever class to replace default return. Pretty explicit in my book.
- orf 7y agoIt’s also really expensive. This new operator works with any Mapping type without needing silly hacks.
- iddan 7y agoFINALLY!
- fyp 7y ago{**d1, **d2} is very natural if you also write javascript where their spread operator looks like: {...d1, ...d2}
- whalesalad 7y agoThis is reason enough to upgrade from Python 2.7 if you are still on it. I use this convenience almost daily.
- TylerE 7y agoNo it isn’t.
- tempay 7y agoOne of the issues with Python 3 is that there isn’t really one killer feature, it’s countless little ones. Many believe 3.6 was the first release where they added up to enough of a benefit (though f-strings are a big help for many projects). Regardless it no longer matters, the Python 2 ecosystem is now rotting as packages drop support. Every week I have to make one or two hot fixes somewhere to forcibly pin to an old version to fix something.
- martopix 7y agoI would definitely mention integer division as a massive change in py3 too. In my field, the @ multiplication operator is also useful.
- teddyh 7y ago> I would definitely mention integer division as a massive change in py3 too. To be fair, you can get that in Python 2 too: from __future__ import division
- edudobay 7y agoFor me, proper handling and distinction of Unicode vs. binary data was a game changer. I don't know if that's related to my first language being non-English, but I remember it being really important to me and a strong reason why I made the switch years ago.
- anentropic 7y agoNice
- ptx 7y agoYay! I was wishing for this feature just a few days ago. It's somewhat analogous to how sorted (since Python 2.4) frees us from having to tediously make copies of lists to sort them in place.
- gnulinux 7y agoYou can already do {**d1, **d2} today for the same effect.
- CameronNemo 7y agoHere I was wondering what a dictionary union was, already having stumbled upon to it and used it. Note that the method you show is slightly different for cases of dict subclasses. The PEP notes the difference: https://www.python.org/dev/peps/pep-0584/#d1-d2 https://www.python.org/dev/peps/pep-0584/#d1-d2.
- misnome 7y agoFantastic. Especially glad they went with | over +, that’s always felt like the natural way I’ve wanted to do this. Looking forward to more set-like operators in the future!
- kbd 7y agoThank goodness sanity prevailed on the operator! We had a whole discussion on HN last time[1] about this, where I argued that dicts are logically subclasses of sets and therefore should share operators. When I saw this headline I accepted my fate of typing the "wrong" operator from now on and liking Python just a tiny bit less for the inconsistency. So glad they reconsidered. [1] https://news.ycombinator.com/item?id=19314646 https://news.ycombinator.com/item?id=19314646
- mixmastamyk 7y agoGuido stated his preference to | and the pep was changed.
- saagarjha 7y agoWhat does this do on duplicate keys? Keep one? Take a predicate?
- realslimjd 7y agoIt keeps the one on the right. They explain it in the PEP: https://www.python.org/dev/peps/pep-0584/ https://www.python.org/dev/peps/pep-0584/
- mixmastamyk 7y agoAKA Last one wins.
- deleted 7y ago[deleted]
- camgunz 7y agoCan't wait for Python 4k where we TOOWTDI all the old stuff.
- kbd 7y agoThe PEP has this section: > The new operators will have the same relationship to the dict.update method as the list concatenate (+) and extend (+=) operators have to list.extend. Note that this is somewhat different from the relationship that |/|= have with set.update; the authors have determined that allowing the in-place operator to accept a wider range of types (as list does) is a more useful design, and that restricting the types of the binary operator's operands (again, as list does) will help avoid silent errors caused by complicated implicit type casting on both sides. Would someone please explain what they mean with regard to being different from set.update, and what could lead to silent errors?
- fulafel 7y agoThe problem with sprinkling operator overloading all over the place in non numerical use is that you as tje reader don't get the context hints provided by method names. I think this change is bad in the overall balance.
- kbd 7y agoThe best way to do dictionary union is already symbolic: {**d1, **d2} This provides a clearer symbolic notation for dictionaries analogous to what's already available with sets. FWIW the pep discusses what this would look like as a method vs an operator: https://www.python.org/dev/peps/pep-0584/#use-a-method https://www.python.org/dev/peps/pep-0584/#use-a-method
- fulafel 7y agoThe best way for in my view is .union(), the new syntax additions are too cryptic.
- choward 7y agoI agree. Back in the day when I used Ruby, I remember one of the arguments for Python being their belief that there should be one way to do things. Found one reference: > There should be one-- and preferably only one --obvious way to do it. https://www.python.org/dev/peps/pep-0020/ https://www.python.org/dev/peps/pep-0020/
- orf 7y agoThere should be one _obvious_ way to do things. Not _one_ way to do things. The operator is better than the dict unpacking-repacking trick, and will become the obvious way to do it.
- anentropic 7y agowe already have `set1 | set2` for set unions and dict keys are basically a set
- wodenokoto 7y agoI haven’t read the entire bug tracking thread, but it seems like people were mostly against it, and have been many times in the past. What made decision makers change their mind and accept this change?
- _-___________-_ 7y agoMost of the bug tracking thread was just about whether `somedictsubclass() | somedictsubclass()` should be `dict()` or `somedictsubclass()` The latter (returns `somedictsubclass`) would cause the `|` operator to rely on the `copy()` method from `dict` which would be the only case where an operator relies on a non-double-underscores method. Based on that, two core devs were against it. The core devs prevailed, and the behaviour will be the former (returns `dict`).
- mrweasel 7y agoIt seems that just using + as the operator was reject because it's: "Too specialised to be used as the default behavior." What does that mean? It works for lists, obviously lists don't need to worry about duplicated values, but it's kind non-intuitive that + won't work for dicts. It think many people view dicts and lists as the same general type of data structure.
- heavenlyblue 7y ago>> It think many people view dicts and lists as the same general type of data structure. Is that a joke or are you from PHP world?
- cal97g 7y agoNice. Dictionary unions are an annoyance in Python currently.
- Rotareti 7y agoI wish there was a union operator for typing as well to replace `Union[str, int]` with just `[str|int]`.
- ash 7y agoDid you mean `str | int`?
- LyndsySimon 7y agoNaively, couldn’t your just overload `or` to make that work?
- ash 7y agoPEP 604 (draft) proposes this: def f(list: List[int | str], param: int | None) -> float | str: pass f([1, "abc"], None) https://www.python.org/dev/peps/pep-0604/ https://www.python.org/dev/peps/pep-0604/
- speedplane 7y agoPython 2 Community: We are in hell, we have to stop working on everything to upgrade to Python 3, there is no straightforward way to upgrade, many of our python 2 libraries haven't been updated, and there are tons of little bugs that are hard to fix. Python 3 Community: Look at thing cool dictionary merging thingy!