![](/img/trans.png)
[英]How to properly import dictionary in python and how to modify imported dictionary
[英]Can't properly modify dictionary in Python class
我在嘗試修改 class 中的字典列表時遇到了一個奇怪的問題。 這是顯示該行為的最小可重現代碼:
from itertools import product
class Test():
def __init__(self, grid):
self.grid = grid
self.pc = [dict(zip(self.grid, v)) for v in product(*self.grid.values())]
for i in range(0, len(self.pc)):
self.pc[i]['sim_options']['id'] = i
grid = {
'k': [5, 10, 15, 20],
'sim_options': [
{'name': 'cosine', 'batched': True},
{'name': 'pearson', 'batched': True}
]
}
t = Test(grid)
我對 output 的期望如下:
[{'k': 5, 'sim_options': {'name': 'cosine', 'batched': True, 'id': 0}},
{'k': 5, 'sim_options': {'name': 'pearson', 'batched': True, 'id': 1}},
{'k': 10, 'sim_options': {'name': 'cosine', 'batched': True, 'id': 2}},
{'k': 10, 'sim_options': {'name': 'pearson', 'batched': True, 'id': 3}},
{'k': 15, 'sim_options': {'name': 'cosine', 'batched': True, 'id': 4}},
{'k': 15, 'sim_options': {'name': 'pearson', 'batched': True, 'id': 5}},
{'k': 20, 'sim_options': {'name': 'cosine', 'batched': True, 'id': 6}},
{'k': 20, 'sim_options': {'name': 'pearson', 'batched': True, 'id': 7}}]
但我得到:
[{'k': 5, 'sim_options': {'name': 'cosine', 'batched': True, 'id': 6}},
{'k': 5, 'sim_options': {'name': 'pearson', 'batched': True, 'id': 7}},
{'k': 10, 'sim_options': {'name': 'cosine', 'batched': True, 'id': 6}},
{'k': 10, 'sim_options': {'name': 'pearson', 'batched': True, 'id': 7}},
{'k': 15, 'sim_options': {'name': 'cosine', 'batched': True, 'id': 6}},
{'k': 15, 'sim_options': {'name': 'pearson', 'batched': True, 'id': 7}},
{'k': 20, 'sim_options': {'name': 'cosine', 'batched': True, 'id': 6}},
{'k': 20, 'sim_options': {'name': 'pearson', 'batched': True, 'id': 7}}]
我不明白我做錯了什么,我沒有遍歷列表,訪問第 i 個列表的'sim_options'
字段並在該字典中創建一個新的鍵值對(“id”:i) ?
似乎字典正在通過引用進行更新,所以無論你對一個做什么,都會發生在另一個身上。
您可以使用id()
function 進行檢查:
for i in range(0, len(self.pc)):
print(id(self.pc[i]['sim_options']))
self.pc[i]['sim_options']['id'] = i
這為'sim_options'
中的兩個字典提供了相同的重復引用標識( 2078935351104
和2078964975104
):
2078935351104
2078964975104
2078935351104
2078964975104
2078935351104
2078964975104
2078935351104
2078964975104
解決此問題的一種方法是復制選項,這將為您提供不同的參考身份。 我已經稍微修改了您的代碼,以便使用copy()
實現這一點。 它還使用enumerate()
來循環索引和項目,當你需要兩者時,它比range(len(...))
更好用。
from itertools import product
from pprint import pprint
class Test:
def __init__(self, grid):
self.grid = grid
self.pc = []
for i, (k, options) in enumerate(product(self.grid["k"], self.grid["sim_options"])):
temp = {"k": k, "sim_options": options.copy()}
temp["sim_options"]["id"] = i
self.pc.append(temp)
def get(self):
return self.pc
grid = {
"k": [5, 10, 15, 20],
"sim_options": [
{"name": "cosine", "batched": True},
{"name": "pearson", "batched": True},
],
}
t = Test(grid)
pprint(t.get())
或者只是使用列表理解構建一個新的字典列表。 我通常覺得這種方式更可取。
self.pc = [
{"k": k, "sim_options": {**option, "id": idx}}
for idx, (k, option) in enumerate(
product(self.grid["k"], self.grid["sim_options"])
)
]
Output:
[{'k': 5, 'sim_options': {'batched': True, 'id': 0, 'name': 'cosine'}},
{'k': 5, 'sim_options': {'batched': True, 'id': 1, 'name': 'pearson'}},
{'k': 10, 'sim_options': {'batched': True, 'id': 2, 'name': 'cosine'}},
{'k': 10, 'sim_options': {'batched': True, 'id': 3, 'name': 'pearson'}},
{'k': 15, 'sim_options': {'batched': True, 'id': 4, 'name': 'cosine'}},
{'k': 15, 'sim_options': {'batched': True, 'id': 5, 'name': 'pearson'}},
{'k': 20, 'sim_options': {'batched': True, 'id': 6, 'name': 'cosine'}},
{'k': 20, 'sim_options': {'batched': True, 'id': 7, 'name': 'pearson'}}]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.