I think Guido has given a direct answer why dict unpacking is not supported
in syntax level,
I can take it and I think it's better to implement a function for dict
unpacking in standard library, just like
from dict_unpack import dict_unpack, pattern as pat
some_dict = {'a': {'b': {'c': 1}, 'd':2}, 'e': 3}
extracted = dict_unpack(some_dict, schema = {'a': {'b': {'c':
pat('V1')}, 'd': pat('V2')}, 'e': pat('V3')})
# extract to a flatten dictionary
v1, v2, v3 = (extracted[k] for k in ('V1', 'V2', 'V3'))
assert (v1, v2, v3) == (1, 2, 3)
As for Steve's confusion,
{'A': 1, **{}} = {'A': 0, **{}} should be just wrong because for any k-v
pair at LHS, the key should be a expression and the value is for unpacking.
{'A': [*a, b]} = {'A': [1, 2, 3]} is welcome, but {'A': 1} = {'A': '1'} is
also something like pattern matching which is out of our topic.
Anyway, this feature will not come true, let's forget it...
I think Jacco is totally correct in following words.
I think most of these problems could be solved with pop and the
occasional list comprehension like this:
a, b, c = [{'a':1,'b':2,'c':3}.pop(key) for key in ('a', 'b', 'c')]
or for your example:
c = {'a': 1, **{'b': 2}} # I suppose this one would generally
# be dynamic, but I need a name here.
a, b = [c.pop(key) for key in ('a', 'b')]
would extract all the keys you need, and has the advantage that
you don't need hardcoded dict structure if you expand it to nested
dicts. It's even less writing, and just as extensible to nested dicts.
And if you dont actually want to destruct (tuples and lists aren't
destroyed either), just use __getitem__ access instead of pop.
But pop cannot work for a nested case.
Feel free to end this topic.
thautwarm
2018-04-10 23:20 GMT+08:00 <python-ideas-request@python.org>:
Send Python-ideas mailing list submissions to
python-ideas@python.org
To subscribe or unsubscribe via the World Wide Web, visit
https://mail.python.org/mailman/listinfo/python-ideas
or, via email, send a message with subject or body 'help' to
python-ideas-request@python.org
You can reach the person managing the list at
python-ideas-owner@python.org
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Python-ideas digest..."
Today's Topics:
1. Re: Is there any idea about dictionary destructing?
(Steven D'Aprano)
2. Re: Is there any idea about dictionary destructing?
(Jacco van Dorp)
3. Re: Start argument for itertools.accumulate() [Was: Proposal:
A Reduce-Map Comprehension and a "last" builtin] (Guido van Rossum)
4. Re: Is there any idea about dictionary destructing?
(Guido van Rossum)
---------- 已转发邮件 ----------
From: "Steven D'Aprano" <steve@pearwood.info>
To: python-ideas@python.org
Cc:
Bcc:
Date: Tue, 10 Apr 2018 19:21:35 +1000
Subject: Re: [Python-ideas] Is there any idea about dictionary destructing?
On Tue, Apr 10, 2018 at 03:29:08PM +0800, Thautwarm Zhao wrote:
I'm focused on the consistency of the language itself.
Consistency is good, but it is not the only factor to consider. We must
guard against *foolish* consistency: adding features just for the sake
of matching some other, often barely related, feature. Each feature must
justify itself, and consistency with something else is merely one
possible attempt at justification.
{key: value_pattern, **_} = {key: value, **_}
If I saw that, I would have no idea what it could even possibly do.
Let's pick the simplest concrete example I can think of:
{'A': 1, **{}} = {'A': 0, **{}}
I cannot interpret what that should do. Is it some sort of
pattern-matching? An update? What is the result? It is obviously some
sort of binding operation, an assignment, but an assignment to what?
Sequence binding and unpacking was obvious the first time I saw it. I
had no problem guessing what:
a, b, c = 1, 2, 3
meant, and once I had seen that, it wasn't hard to guess what
a, b, c = *sequence
meant. From there it is easy to predict extended unpacking. But I can't
say the same for this.
I can almost see the point of:
a, b, c, = **{'a': 1, 'b': 2, 'c': 3}
but I'm having trouble thinking of a situation where I would actually
use it. But your syntax above just confuses me.
The reason why it's important is that, when destructing/constructing for
built-in data structures are not supported completely,
people might ask why "[a, *b] = c" is ok but "{"a": a, **b} = c" not.
People can ask all sorts of questions. I've seen people ask why Python
doesn't support line numbers and GOTO. We're allowed to answer "Because
it is a bad idea", or even "Because we don't think it is good enough to
justify the cost".
If only multiple assignment is supported, why "(a, (b, c)) = d" could be
ok? It's exactly destructing!
That syntax is supported. I don't understand your point here.
>> {'a': a, 'b': b, **c} = {'a': 1, **{'b': 2}}
SyntaxError: can't assign to literal
Above example could be confusing in some degree, I think.
I have no idea what you expect it to do. Even something simpler:
{'a': a} = {'a': 2}
leaves me in the dark.
--
Steve
---------- 已转发邮件 ----------
From: Jacco van Dorp <j.van.dorp@deonet.nl>
To: python-ideas@python.org
Cc:
Bcc:
Date: Tue, 10 Apr 2018 11:52:40 +0200
Subject: Re: [Python-ideas] Is there any idea about dictionary destructing?
I must say I can't really see the point either. If you say like:
{'a': a, 'b': b, **c} = {'a': 1, **{'b': 2}}
Do you basically mean:
c = {'a': 1, **{'b': 2}}
a = c.pop("a")
b = c.pop("b") # ?
That's the only thing I could think of.
I think most of these problems could be solved with pop and the
occasional list comprehension like this:
a, b, c = [{'a':1,'b':2,'c':3}.pop(key) for key in ('a', 'b', 'c')]
or for your example:
c = {'a': 1, **{'b': 2}} # I suppose this one would generally
# be dynamic, but I need a name here.
a, b = [c.pop(key) for key in ('a', 'b')]
would extract all the keys you need, and has the advantage that
you don't need hardcoded dict structure if you expand it to nested
dicts. It's even less writing, and just as extensible to nested dicts.
And if you dont actually want to destruct (tuples and lists aren't
destroyed either), just use __getitem__ access instead of pop.
2018-04-10 11:21 GMT+02:00 Steven D'Aprano <steve@pearwood.info>:
On Tue, Apr 10, 2018 at 03:29:08PM +0800, Thautwarm Zhao wrote:
I'm focused on the consistency of the language itself.
Consistency is good, but it is not the only factor to consider. We must
guard against *foolish* consistency: adding features just for the sake
of matching some other, often barely related, feature. Each feature must
justify itself, and consistency with something else is merely one
possible attempt at justification.
{key: value_pattern, **_} = {key: value, **_}
If I saw that, I would have no idea what it could even possibly do.
Let's pick the simplest concrete example I can think of:
{'A': 1, **{}} = {'A': 0, **{}}
I cannot interpret what that should do. Is it some sort of
pattern-matching? An update? What is the result? It is obviously some
sort of binding operation, an assignment, but an assignment to what?
Sequence binding and unpacking was obvious the first time I saw it. I
had no problem guessing what:
a, b, c = 1, 2, 3
meant, and once I had seen that, it wasn't hard to guess what
a, b, c = *sequence
meant. From there it is easy to predict extended unpacking. But I can't
say the same for this.
I can almost see the point of:
a, b, c, = **{'a': 1, 'b': 2, 'c': 3}
but I'm having trouble thinking of a situation where I would actually
use it. But your syntax above just confuses me.
The reason why it's important is that, when destructing/constructing for
built-in data structures are not supported completely,
people might ask why "[a, *b] = c" is ok but "{"a": a, **b} = c" not.
People can ask all sorts of questions. I've seen people ask why Python
doesn't support line numbers and GOTO. We're allowed to answer "Because
it is a bad idea", or even "Because we don't think it is good enough to
justify the cost".
If only multiple assignment is supported, why "(a, (b, c)) = d" could be
ok? It's exactly destructing!
That syntax is supported. I don't understand your point here.
>> {'a': a, 'b': b, **c} = {'a': 1, **{'b': 2}}
SyntaxError: can't assign to literal
Above example could be confusing in some degree, I think.
I have no idea what you expect it to do. Even something simpler:
{'a': a} = {'a': 2}
leaves me in the dark.
--
Steve
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/
---------- 已转发邮件 ----------
From: Guido van Rossum <guido@python.org>
To: "Stephen J. Turnbull" <turnbull.stephen.fw@u.tsukuba.ac.jp>
Cc: Tim Peters <tim.peters@gmail.com>, Python-Ideas <
python-ideas@python.org>
Bcc:
Date: Tue, 10 Apr 2018 08:05:18 -0700
Subject: Re: [Python-ideas] Start argument for itertools.accumulate()
[Was: Proposal: A Reduce-Map Comprehension and a "last" builtin]
On Mon, Apr 9, 2018 at 11:35 PM, Stephen J. Turnbull <
turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Tim Peters writes:
"Sum reduction" and "running-sum accumulation" are primitives in
many peoples' brains.
I wonder what Kahneman would say about that. He goes to some length
to explain that people are quite good (as human abilities go) at
perceiving averages over sets but terrible at summing the same. Maybe
they substitute the abstraction of summation for the ability to
perform the operation?
[OT] How is that human ability tested? I am a visual learner and I would
propose that if you have a set of numbers, you can graph it in different
ways to make it easier to perceive one or the other (or maybe both):
- to emphasize the average, draw a line graph -- in my mind I draw a line
through the average (getting the trend for free)
- to emphasize the sum, draw a histogram -- in my mind I add up the sizes
of the bars
--
--Guido van Rossum (python.org/~guido)
---------- 已转发邮件 ----------
From: Guido van Rossum <guido@python.org>
To: Python-Ideas <python-ideas@python.org>
Cc:
Bcc:
Date: Tue, 10 Apr 2018 08:20:11 -0700
Subject: Re: [Python-ideas] Is there any idea about dictionary destructing?
Here's one argument why sequence unpacking is more important than dict
unpacking.
Without sequence unpacking, you have a long sequence, to get at a specific
item you'd need to use indexing, where you often end up having to remember
the indices for each type of information. Say you have points of the form
(x, y, z, t), to get at the t coordinate you'd have to write p[3]. With
sequence unpacking you can write
x, y, z, t = p
and then you can use the individual variables in the subsequent code.
However if your point had the form {'x': x, 'y': y, 'z': z, 't': t}, you
could just write p['t']. This is much more mnemonic than p[3].
All the rest follows -- after a while extended forms of iterable unpacking
start making sense. But for dicts the use case is just much less common.
(If you're doing a lot of JSON you might have a different view on that.
You should probably use some kind of schema-guided parser though.)
--
--Guido van Rossum (python.org/~guido)
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas