2

我正在看大卫比兹利的演讲。在 23:20 分钟,他打开包装做了一些“魔术”,我很难理解。

“魔法线”是

fail = [ { **row, 'DBA Name': row['DBA Name'].replace("'",'').upper() } for row in fail ]

我搜索了类似的示例,但找不到任何示例。你能解释一下这段代码发生了什么吗?你能指出一些类似的例子吗?

4

2 回答 2

2

该片段在添加新元素的同时解压缩字典文字中已经存在的映射row。一个简化的例子证明了这一点:

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

这种解包仅在PEP 448引入的 Python >= 3.5 中可用;在以前的版本中,它是一个SyntaxError.

于 2017-08-18T14:16:55.010 回答
1

只是解{**row}包字典(在 python-3.5+ 中允许使用):

>>> row = {'DBA Name': "make 'this' now", 'b': 2}
>>> {**row}
{'DBA Name': "make 'this' now", 'b': 2}

本质上,这只是复制,row因为您将字典解压缩到字典中。

第二部分是普通的字典文字语法:

>>> {'DBA Name': row['DBA Name'].replace("'",'').upper() }
{'DBA Name': 'MAKE THIS NOW'}

“神奇”位是字典将唯一键映射到某个值,因此这本质上是字典的副本并用新值row替换键。'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()

但这在理解中不起作用(理解中的赋值是 a SyntaxError)所以你需要一些“魔法”(或调用特殊方法)。


但是您也可以使用嵌套理解来做到这一点(它更慢但可能不那么神奇):

[        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()]
于 2017-08-18T14:50:55.187 回答