想象一個理論片段:# just for this example: `bad_structure` contains a list of dicts with different keys# for the same semanticbad_structure = [{'path': '/dir/one'}, {'subdir': '/dir/two'}]# i want to turn this into# { '/dir/one': some_func('/dir/one'),# '/dir/two': some_func('/dir/two')}result = {}for e in bad_structure: # calculate a value which we will need more than once (here the key) p = next(k for k in ('path', 'subdir') if k in e) result[p] = some_func(p)我現在想把它變成一個dict理解,我的第一種方法是這樣的:bad_structure = [{'path': '/dir/one'}, {'path': '/dir/two'}]result = {next(k for k in ('path', 'subdir') if k in e): some_func(next(k for k in ('path', 'subdir') if k in e)) for e in bad_structure}其中包含兩次丑陋、容易出錯且速度慢的“計算”。我想將其重寫為 s.th。喜歡result = {p: some_func(p) for p = next(k for k in ('path', 'subdir') if k in e) for e in bad_structure}這當然不是有效的 Python 代碼..在 Python 中這樣的事情可能嗎?為了澄清:我不關心理解語法,而是在沒有單獨變量聲明的情況下重用計算(這在封閉表達式中是不可能的)
2 回答

一只萌萌小番薯
TA貢獻1795條經驗 獲得超7個贊
是的!Python 3.8 引入了“賦值運算符” :=
,它允許您在單個表達式的局部范圍內定義一個變量(例如,推導式)。在您的示例中,您將執行以下操作:
result = {(p := next(k for k in ('path', 'subdir') if k in e)): some_func(p) for e in bad_structure}
免責聲明:這在 3.8 之前的任何 python 版本中都不起作用。

慕妹3242003
TA貢獻1824條經驗 獲得超6個贊
您可以使用中間推導來綁定名稱:
result = {
p: some_func(p)
# bind intermediate result to p
for p in ( # nested comprehension to produce intermediate result
next(k for k in ('path', 'subdir') if k in e)
for e in bad_structure
)
}
它不是直接映射到兩個單獨的表達式,而是首先映射到一個公共表達式,然后再映射到兩個單獨的表達式。
您可以傳遞和重命名任意數量的值。在內部理解中創建一個元組,并在外部理解中將其解包為多個名稱。
result = {
p: some_func(e, p)
for e, p in (
(e, next(iter(e)))
for e in bad_structure
)
}
添加回答
舉報
0/150
提交
取消