Python : defaultdict 每个值都会更新
Python : defaultdict every value is updated
我在一个愚蠢的问题上工作了一个多小时,但我无法找出解决方案。
我创建一个带有初始列表的 defaultdict(list) 并通过 for 循环更新这些列表。
但是,每次我更新一个值时,所有其他值都会更新为相同的值。
有人可以帮我吗?
这是我的代码:
from collections import defaultdict
base = ["coucou", "salut", "tchao"]
initial_vector = [0]*len(base)
dict_vectorized_documents = defaultdict(lambda: initial_vector)
inversed_index = {"coucou": [(1, 3), (100, 4)], "salut": [(1, 1), (99, 2), (33, 3)], "tchao": [(1, 5)]}
for i, word in enumerate(base):
print(word)
for element in inversed_index[word]:
print(element[0])
print(i)
print(element[1])
print(dict_vectorized_documents[element[0]][i])
dict_vectorized_documents[element[0]][i] = element[1]
print(dict_vectorized_documents)
print(dict_vectorized_documents)
这是我 运行 时的日志:
coucou
1
0
3
0
defaultdict(<function <lambda> at 0x7fcc5fac1f28>, {1: [3, 0, 0]})
100
0
4
3
defaultdict(<function <lambda> at 0x7fcc5fac1f28>, {1: [4, 0, 0], 100: [4, 0, 0]})
salut
1
1
1
0
defaultdict(<function <lambda> at 0x7fcc5fac1f28>, {1: [4, 1, 0], 100: [4, 1, 0]})
99
1
2
1
defaultdict(<function <lambda> at 0x7fcc5fac1f28>, {1: [4, 2, 0], 99: [4, 2, 0], 100: [4, 2, 0]})
33
1
3
2
defaultdict(<function <lambda> at 0x7fcc5fac1f28>, {1: [4, 3, 0], 99: [4, 3, 0], 100: [4, 3, 0], 33: [4, 3, 0]})
tchao
1
2
5
0
非常感谢!
因为您要在 defaultdict
工厂中返回 相同的列表 。
最简单的解决方案?用 list
:
显式复制它
>>> from collections import defaultdict
>>> base = ["coucou", "salut", "tchao"]
>>> initial_vector = [0]*len(base)
>>> dict_vectorized_documents = defaultdict(lambda: list(initial_vector))
这里是一个人为的例子,可能会更清楚:
>>> initial_list = [0, 0, 0]
>>> def get_initial():
... return initial_list
...
>>> d = {}
>>> for k, i in zip(['key1','key2','key3'],range(3)):
... new_list = get_initial()
... new_list[i] = 'mutated'
... d[k] = new_list
...
>>> d
{'key2': ['mutated', 'mutated', 'mutated'], 'key3': ['mutated', 'mutated', 'mutated'], 'key1': ['mutated', 'mutated', 'mutated']}
所以 new_list
毕竟不是新列表。但是,如果我们这样做:
>>> initial_list = [0, 0, 0]
>>> def get_initial():
... return list(initial_list)
...
>>> d = {}
>>> for k, i in zip(['key1','key2','key3'],range(3)):
... new_list = get_initial()
... new_list[i] = 'mutated'
... d[k] = new_list
...
>>> d
{'key2': [0, 'mutated', 0], 'key3': [0, 0, 'mutated'], 'key1': ['mutated', 0, 0]}
>>>
难道你不应该在 defaultdict 对象上追加,例如:
dict_vectorized_documents[element[0]][i].append(element[1])
我在一个愚蠢的问题上工作了一个多小时,但我无法找出解决方案。 我创建一个带有初始列表的 defaultdict(list) 并通过 for 循环更新这些列表。 但是,每次我更新一个值时,所有其他值都会更新为相同的值。 有人可以帮我吗? 这是我的代码:
from collections import defaultdict
base = ["coucou", "salut", "tchao"]
initial_vector = [0]*len(base)
dict_vectorized_documents = defaultdict(lambda: initial_vector)
inversed_index = {"coucou": [(1, 3), (100, 4)], "salut": [(1, 1), (99, 2), (33, 3)], "tchao": [(1, 5)]}
for i, word in enumerate(base):
print(word)
for element in inversed_index[word]:
print(element[0])
print(i)
print(element[1])
print(dict_vectorized_documents[element[0]][i])
dict_vectorized_documents[element[0]][i] = element[1]
print(dict_vectorized_documents)
print(dict_vectorized_documents)
这是我 运行 时的日志:
coucou
1
0
3
0
defaultdict(<function <lambda> at 0x7fcc5fac1f28>, {1: [3, 0, 0]})
100
0
4
3
defaultdict(<function <lambda> at 0x7fcc5fac1f28>, {1: [4, 0, 0], 100: [4, 0, 0]})
salut
1
1
1
0
defaultdict(<function <lambda> at 0x7fcc5fac1f28>, {1: [4, 1, 0], 100: [4, 1, 0]})
99
1
2
1
defaultdict(<function <lambda> at 0x7fcc5fac1f28>, {1: [4, 2, 0], 99: [4, 2, 0], 100: [4, 2, 0]})
33
1
3
2
defaultdict(<function <lambda> at 0x7fcc5fac1f28>, {1: [4, 3, 0], 99: [4, 3, 0], 100: [4, 3, 0], 33: [4, 3, 0]})
tchao
1
2
5
0
非常感谢!
因为您要在 defaultdict
工厂中返回 相同的列表 。
最简单的解决方案?用 list
:
>>> from collections import defaultdict
>>> base = ["coucou", "salut", "tchao"]
>>> initial_vector = [0]*len(base)
>>> dict_vectorized_documents = defaultdict(lambda: list(initial_vector))
这里是一个人为的例子,可能会更清楚:
>>> initial_list = [0, 0, 0]
>>> def get_initial():
... return initial_list
...
>>> d = {}
>>> for k, i in zip(['key1','key2','key3'],range(3)):
... new_list = get_initial()
... new_list[i] = 'mutated'
... d[k] = new_list
...
>>> d
{'key2': ['mutated', 'mutated', 'mutated'], 'key3': ['mutated', 'mutated', 'mutated'], 'key1': ['mutated', 'mutated', 'mutated']}
所以 new_list
毕竟不是新列表。但是,如果我们这样做:
>>> initial_list = [0, 0, 0]
>>> def get_initial():
... return list(initial_list)
...
>>> d = {}
>>> for k, i in zip(['key1','key2','key3'],range(3)):
... new_list = get_initial()
... new_list[i] = 'mutated'
... d[k] = new_list
...
>>> d
{'key2': [0, 'mutated', 0], 'key3': [0, 0, 'mutated'], 'key1': ['mutated', 0, 0]}
>>>
难道你不应该在 defaultdict 对象上追加,例如:
dict_vectorized_documents[element[0]][i].append(element[1])