
On 2016-05-26 00:41, Ethan Furman wrote:
On 05/25/2016 03:52 PM, Michael Selik wrote:
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.
Ugh, no. That is not dict unpacking, it's dict matching and unpacking, which is way beyond the simplicity of just unpacking.
On Wed, May 25, 2016 at 4:14 PM Ethan Furman 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 =
Good point. So it should just be:
a, b = mapping
or a, b, **_ = mapping # when you don't care about the rest
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
I think that most Pythonistas would say:
a, b = 1, 2 # look ma! no round brackets!
Unpacking a dict should mirror a dict display.
py> {'x': a, 'y': b} = {'x': 1, 'y': 2}
Absolutely not, at least not for the simple case. A simple tuple/list unpack looks like
a, b, c = an_iterable
while a more complicated one looks like
a, b, c = an_iterable[7], an_iterable[3], an_iterable[10]
So a simple dict unpack should look like
some_dict = dict(a=99, b=44, c=37) a, b, c = some_dict
and if we don't need all the items
a, b, **_ = some_dict
and if we want to rename the keys on extraction
x, y, z = some_dict['a'], some_dict['b'], some_dict['c']
or, as Random pointed out
x, y, z = [some_dict[k] for k in ('a', 'b', 'c')]
which has a nice symmetry to it.
Could we use 'as', which is already used for renaming in imports? a as x, b as y, c as z = some_dict or, perhaps: 'a' as x, 'b' as y, 'c' as z = some_dict which would cater for keys that aren't valid as identifiers.
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.
And as I have mentioned, matching syntax is out-of-scope for an unpacking proposal. At most, it should be a "let's not paint ourselves into a corner" type of concern -- and I must admit I don't see why
a, b, c = some_dict
rules out
{'x': a, 'y':b} = some_dict
as a pattern-matching construct.
On Wed, May 25, 2016 at 11:18 AM Paul Moore 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}
Since you've repeated yourself, I will too. ;)
The parenthesis are legal, but usually unnecessary noise, when creating/unpacking a tuple.