Got it, thank you. I'll go and check it out! On Nov 11, 2017 01:22, "Jelle Zijlstra" <jelle.zijls...@gmail.com> wrote:
> > > 2017-11-10 19:53 GMT-08:00 Ben Usman <bigoban...@gmail.com>: > >> The following works now: >> >> seq = [1, 2] >> d = {'c': 3, 'a': 1, 'b': 2} >> >> (el1, el2) = *seq >> el1, el2 = *seq >> head, *tail = *seq >> >> seq_new = (*seq, *tail) >> dict_new = {**d, **{'c': 4}} >> >> def f(arg1, arg2, a, b, c): >> pass >> >> f(*seq, **d) >> >> It seems like dict unpacking syntax would not be fully coherent with >> list unpacking syntax without something like: >> >> {b, a, **other} = **d >> >> Because iterables have both syntax for function call unpacking and >> "rhs in assignment unpacking" and dict has only function call >> unpacking syntax. >> >> I was not able to find any PEPs that suggest this (search keywords: >> "PEP 445 dicts", "dictionary unpacking assignment", checked PEP-0), >> however, let me know if I am wrong. >> >> It was discussed at great length on Python-ideas about a year ago. There > is a thread called "Unpacking a dict" from May 2016. > > >> The main use-case, in my understating, is getting shortcuts to >> elements of a dictionary if they are going to be used more then >> ones later in the scope. A made-up example is using a config to >> initiate a bunch of things with many config arguments with long >> names that have overlap in keywords used in initialization. >> >> One should either write long calls like >> >> start_a(config['parameter1'], config['parameter2'], >> config['parameter3'], config['parameter4']) >> >> start_b(config['parameter3'], config['parameter2'], >> config['parameter3'], config['parameter4']) >> >> many times or use a list-comprehension solution mentioned above. >> >> It becomes even worse (in terms of readability) with nested structures. >> >> start_b(config['group2']['parameter3'], config['parameter2'], >> config['parameter3'], config['group2']['parameter3']) >> >> >> ## Rationale >> >> Right now this problem is often solved using [list] comprehensions, >> but this is somewhat verbose: >> >> a, b = (d[k] for k in ['a', 'b']) >> >> or direct per-instance assignment (looks simple for with >> single-character keys, but often becomes very verbose with >> real-world long key names) >> >> a = d['a'] >> b = d['b'] >> >> Alternatively one could have a very basic method\function >> get_n() or __getitem__() accepting more then a single argument >> >> a, b = d.get_n('a', 'b') >> a, b = get_n(d, 'a', 'b') >> a, b = d['a', 'b'] >> >> All these approaches require verbose double-mentioning of same >> key. It becomes even worse if you have nested structures >> of dictionaries. >> >> ## Concerns and questions: >> >> 0. This is the most troubling part, imho, other questions >> are more like common thoughts. It seems (to put it mildly) >> weird that execution flow depends on names of local variables. >> >> For example, one can not easily refactor these variable names. However, >> same is true for dictionary keys anyway: you can not suddenly decide >> and refactor your code to expect dictionaries with keys 'c' and >> 'd' whereas your entire system still expects you to use dictionaries >> with keys 'a' and 'b'. A counter-objection is that this specific >> scenario is usually handled with record\struct-like classes with >> fixed members rather then dicts, so this is not an issue. >> >> Quite a few languages (closure and javascript to name a few) seem >> to have this feature now and it seems like they did not suffer too >> much from refactoring hell. This does not mean that their approach >> is good, just that it is "manageable". >> >> 1. This line seems coherent with sequence syntax, but redundant: >> {b, a, **other} = **d >> >> and the following use of "throwaway" variable just looks poor visually >> {b, a, **_} = **d >> >> could it be less verbose like this >> {b, a} = **d >> >> but it is not very coherent with lists behavior. >> >> E.g. what if that line did not raise something like "ValueError: >> Too many keys to unpack, got an unexpected keyword argument 'c'". >> >> 2. Unpacking in other contexts >> >> {self.a, b, **other} = **d >> >> should it be interpreted as >> self.a, b = d['a'], d['b'] >> >> or >> >> self.a, b = d['self.a'], d['b'] >> >> probably the first, but what I am saying is that these name-extracting >> rules should be strictly specified and it might not be trivial. >> >> --- >> Ben >> >> _______________________________________________ >> Python-Dev mailing list >> Python-Dev@python.org >> https://mail.python.org/mailman/listinfo/python-dev >> Unsubscribe: https://mail.python.org/mailman/options/python-dev/jelle. >> zijlstra%40gmail.com >> >> >
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com