Python 列表理解中的奇怪解包

Python 列表理解中的奇怪解包,python,python-3.x,list-comprehension,iterable-unpacking,pep448,Python,Python 3.x,List Comprehension,Iterable Unpacking,Pep448,我在看。在23:20分,他在解包时施展了一些“魔法”,这让我很难理解 “魔线”是 我搜索过类似的例子,但没有找到。你能解释一下这段代码是怎么回事吗?你能给我指出一些类似的例子吗?在添加新元素的同时,代码片段正在解压字典文本中已经存在的映射行。一个简单的示例演示了这一点: >>> r = {'a':1, 'b':2} >>> {**r, 'Spam': 20} {'Spam': 20, 'a': 1, 'b': 2} 此解包仅在Pythons>=3.5

我在看。在23:20分,他在解包时施展了一些“魔法”,这让我很难理解

“魔线”是


我搜索过类似的例子,但没有找到。你能解释一下这段代码是怎么回事吗?你能给我指出一些类似的例子吗?

在添加新元素的同时,代码片段正在解压字典文本中已经存在的映射
行。一个简单的示例演示了这一点:

>>> r = {'a':1, 'b':2}    
>>> {**r, 'Spam': 20}
{'Spam': 20, 'a': 1, 'b': 2}

此解包仅在Pythons>=3.5中可用,如所介绍的;在以前的版本中,它是一个
SyntaxError
{**row}
只是解压字典(在python-3.5+中允许使用文本):

本质上,这只是复制
,因为您将字典解包到字典中

第二部分是标准字典文字语法:

>>> {'DBA Name': row['DBA Name'].replace("'",'').upper() }
{'DBA Name': 'MAKE THIS NOW'}
“神奇”的一点是,字典将唯一键映射到某个值,因此这实际上是
字典的副本,并用新值替换
'DBA Name'
键。这是因为文字是从左到右解释的:

>>> { **row, 'DBA Name': row['DBA Name'].replace("'",'').upper() }
{'DBA Name': 'MAKE THIS NOW', 'b': 2}
通常,您只需创建字典的副本并替换密钥:

>>> newrow = row.copy()
>>> newrow['DBA Name'] = row['DBA Name'].replace("'",'').upper()
但这在理解中不起作用(理解中的赋值是一个
语法错误
),因此需要一些“魔法”(或调用特殊方法)


但是你也可以用嵌套的理解(速度较慢,但可能不那么神奇):

缩进可能看起来有点不对劲,但我发现这样更容易形象化,您也可以只使用一行:

[k: v.replace("'",'').upper() if key == 'DBA Name' else v for row in fail for k, v in row.items()]

我不知道您可以在解包时添加新元素。这在官方文件中吗?我找不到它:/@alec_djinn是的,PEP 448描述了它,语言参考也描述了它,请看一下(参见
**
上的句子)。谢谢!我错过了字典显示的段落。@alec_djinn:这个想法是让解包的东西只是将额外的定义转储到一个“普通的”
dict
literal中。它不是“添加新元素”,因为它假设新的
dict
与旧的直接关联,并且它所基于的只有一个旧的
dict
。但是您可以解压多个
dict
s,在它们之前、之间或之后都有键/值对,并且它遵循与常规
dict
文本相同的规则(顺序基于第一次看到键的时间,但值来自键的最后一次出现)@JimFasarakisHilliard:另一篇文章是规范的“what does
**
是什么意思的文章”,并且有一个专门针对这个案例的答案。@mseifer:同上;我支持副本。我可以将两者链接起来,但是参数问题的焦点是非常不同的,在9个答案和许多页的向下滚动之前,你实际上看不到任何关于PEP 448解包概括的内容(这个答案甚至不是OP问题的好答案)。是PEP 448特定解包概括的更好目标;这个问题和最上面的答案都是关于OP的问题。
>>> newrow = row.copy()
>>> newrow['DBA Name'] = row['DBA Name'].replace("'",'').upper()
[        k: v.replace("'",'').upper() if key == 'DBA Name' else v 
 for row in fail 
     for k, v in row.items()]
[k: v.replace("'",'').upper() if key == 'DBA Name' else v for row in fail for k, v in row.items()]