我有一個字典,其中一個鍵的值為 list
example = {"a":1,"b":[1,2]}
我正在嘗試解壓縮example["b"]并創建具有單獨example["b"]值的相同字典的串列。
output = [{"a":1,"b":1},{"a":1,"b":2}]
我試圖使用 for 回圈來理解 dict 串列的解包和重建,但我看到了一個奇怪的行為 - 可能是我在這里遺漏了一些簡單的東西......
iter = example.get("b")
new_list = []
for p in iter:
print(f"p is {p}")
tmp_dict = example
tmp_dict["b"] = p
print(tmp_dict)
new_list.append(tmp_dict)
print(new_list)
輸出
p is 1
{'a': 1, 'b': 1}
p is 2
{'a': 1, 'b': 2}
[{'a': 1, 'b': 2}, {'a': 1, 'b': 2}]
為什么串列中的第一個 dict 被分配,example["b"] = 2盡管第一個print()顯示了p is 1?
uj5u.com熱心網友回復:
為什么串列中的第一個 dict 被分配 example["b"] = 2 盡管第一個 print() 顯示 p 是 1
因為它們都是相同的 dict: example。如果您print(id(tmp_dict))在回圈內部,您可以看到這一點,并且您會看到它始終是同一個物件。請參閱id( ) 函式的用途是什么?(這是一個 python 2 的問題,但也適用于 python 3)
如果您想保留您的代碼,您只需要創建一個新字典example并將其分配給tmp_dict. 請參閱如何復制字典并僅編輯副本
tmp_dict = example.copy()
雖然這基本上復制整個字典只是為了丟棄b密鑰,所以你可以簡單地做:
tmp_dict = {"a": example["a"]}
請注意,iter不建議您將其用作變數名,因為在 python 中iter已經意味著某些東西
相反,這是一種適用于所有情況的通用方法,無需對任何鍵進行硬編碼。讓我們首先創建一個臨時字典,其中所有值都是串列。
temp = {k: v if isinstance(v, list) else [v] for k, v in example.items()}
這使我們能夠獲得tempdict 中所有值的串列作為串列串列。
我們想要這個字典所有值的乘積。temp為此,我們可以使用該itertools.product函式,并將我們的串列解包到它的引數中。
在每次迭代中,結果元組將有一個temp字典的每個鍵的值,所以我們需要做的就是zip使用我們的元組,并從這些鍵值對中創建一個字典。這給了我們串列元素!
import itertools
keys = list(temp.keys())
vals = list(temp.values())
result = []
for vals_product in itertools.product(*vals):
d = dict(zip(keys, vals_product))
result.append(d)
這給出了所需的結果:
[{'a': 1, 'b': 1}, {'a': 1, 'b': 2}]
這甚至適用于example具有更多鍵的:
example = {'a': 1, 'b': [1, 2], 'c': [1, 2, 3]}
這使:
[{'a': 1, 'b': 1, 'c': 1},
{'a': 1, 'b': 1, 'c': 2},
{'a': 1, 'b': 1, 'c': 3},
{'a': 1, 'b': 2, 'c': 1},
{'a': 1, 'b': 2, 'c': 2},
{'a': 1, 'b': 2, 'c': 3}]
uj5u.com熱心網友回復:
只是一個小的更正: dict() 的用法
example = {"a":1,"b":[1,2]}
iter = example.get("b")
new_list = []
for p in iter:
print(f"p is {p}")
tmp_dict = dict(example)
tmp_dict["b"] = p
print(tmp_dict)
new_list.append(tmp_dict)
print(new_list)
輸出如下: [{'a': 1, 'b': 1}, {'a': 1, 'b': 2}]
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/518404.html
標籤:Python列表字典
