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