2017-08-18 64 views
2

我在觀看a lecture from David Beazley。在23:20分鐘,他做了一些「魔術」的解包,我很難理解。奇怪的解開列表理解

「神奇線」是

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

...我已經尋找類似的例子,但我找不到任何。你能解釋一下這段代碼發生了什麼嗎?你能指點我一些類似的例子嗎?

+0

@JimFasarakisHilliard:其他職位是規範的「是什麼''**後的意思,並有一個明確的答案涉及此案。 –

+0

@ MSeifert:同上你;我支持重複。 –

回答

2

這段代碼將字典文字中的現有映射row解包,同時添加一個新元素。一個簡單的例子證明了該:

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

這拆包僅在蟒蛇可用> = 3.5與PEP 448引入;在以前的版本中它是一個SyntaxError

+0

我不知道你可以在開箱時添加一個新元素。這是在官方文件?我無法找到它:/ –

+0

@alec_djinn是的,PEP 448描述了它,語言參考也是如此,請查看[字典顯示](https://docs.python.org/3/reference/expressions.html #dictionary-displays)(見'**'上的句子)。 –

+0

謝謝!我錯過了字典顯示段落。 –

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() 

但是,這並不在解析的工作(任務內部理解是一個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()]