Re: [Python-ideas] Python-ideas Digest, Vol 137, Issue 40
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,
{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?
{'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
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"
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
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
: 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
To: "Stephen J. Turnbull" Cc: Tim Peters , 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
To: Python-Ideas 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
participants (1)
-
Thautwarm Zhao