
I'm responding here to Sven, Random832, and Ethan. On Wed, May 25, 2016 at 10:08 AM Sven R. Kunze <srkunze@mail.de> wrote:
I for one find this one of the shortest proposals compared to other recent proposals I have seen. :)
If it's easy to explain, it might be a good idea :-) On Wed, May 25, 2016 at 10:40 AM Random832 <random832@fastmail.com> wrote:
On Wed, May 25, 2016, at 09:11, Michael Selik wrote:
Clojure also supports mapping destructuring. Let's add that to Python!
py> mapping = {"a": 1, "b": 2, "c": 3} py> {"a": x, "b": y, "c": z} = mapping
How is this better than: py> mapping = {"a": 1, "b": 2, "c": 3} py> x, y, z = mapping[k] for k in ("a", "b", "c")
I think the thread has formed a consensus that there are at least 2 clear use cases for unpacking. Not surprisingly, they're the same use cases for both tuple unpacking and dict unpacking. 1. declarative schema validation while simultaneously binding variables 2. declaratively extracting a subset of the elements In your example, what if the dict has more keys than you are looping over? Look at the other part of my proposal: py> mapping = {"a": 1, "b": 2, "c": 3} py> {"a": x, "b": y} = mapping Traceback: ValueError: too many keys to unpack I really like Sven's example. py> mapping = {"a": 1, "b": 2, "c": 3} py> {"a": x, "b": y, "c": 2} = mapping Traceback: ValueError: key 'c' does not match value 2 Even if we don't implement this feature in the first version of dict unpacking, we should keep the option open. On Wed, May 25, 2016 at 4:14 PM Ethan Furman <ethan@stoneleaf.us> wrote:
The proposal is this: a, b = **mapping
The advantages: - much more readable - less duplication
Why doesn't that work for tuple unpacking? py> a, b = *iterable SyntaxError Whatever the reasons, that syntax wasn't chosen for tuple unpacking. Dict unpacking should mimic tuple unpacking. If I saw ``a, b = **mapping`` I would expect ``a, b = *iterable``. Unpacking a tuple mirrors a tuple display. py> (a, b) = (1, 2) py> (a, b) = (1, 2, 3) ValueError: too many values to unpack, expected 2 Unpacking a dict should mirror a dict display. py> {'x': a, 'y': b} = {'x': 1, 'y': 2} py> {'x': a, 'y': b} = {'x': 1, 'y': 2, 'z': 3} ValueError: too many keys to unpack, expected {'x', 'y'} As Brendan and others have mentioned, the more concise syntax you're proposing will not support non-string keys and cannot be enhanced to support Erlang/Clojure/etc-style matching on values. On Wed, May 25, 2016 at 11:18 AM Paul Moore <p.f.moore@gmail.com> wrote:
get a set of elements and *ignore* the rest:
If it's just one or two, that's easy. Use an underscore to indicate you don't care. Again, I'm trying to mirror a dict display. This is the same way that tuple unpacking solves the problem. py> (a, b, _) = (1, 2, 3) py> {'x': a, 'y': b, 'z': _} = {'x': 1, 'y': 2, 'z': 3} If you need to ignore many, we need to extend dict unpacking the same way that tuple unpacking was extended in PEP 3132. py> (a, b, *rest) = (1, 2, 3, 4) py> a, b, rest (1, 2, (3, 4)) py> {'x': a, 'y', b, **rest} = {'x': 1, 'y': 2, 'z': 3, 'w': 4} py> a, b, rest (1, 2, {'w': 4, 'z': 3}) Sure, **rest isn't valid in a dict display, but it's the same with tuple unpacking: *rest isn't valid in a tuple display.