从元组创建的字典列表中的字典值未正确更新
Dictionary value in Dictionary list created from tuple doesn't update correctly
当我在列表(从元组创建)中的字典上创建新字典值时,字典值更新所有相似的字典条目,而不是我想要的单个条目:
import itertools
import random
seq = [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]
# Create combinations of ABCD -> AB, AC, AD, BA, BB, BC [...] ABD [...] ABCD
allCombinations = []
for i in range(2, len(seq) + 1):
combinationTuple = list(itertools.combinations(seq, i)) # Produces tuples (immutable) of dictionaries
allCombinations += combinationTuple
# allCombinations = [({'Item': 'A'}, {'Item': 'B'}), ({'Item': 'A'}, {'Item': 'C'}), ({'Item': 'A'}, {'Item': 'D'}), ({'Item': 'B'}, {'Item': 'C'}), ({'Item': 'B'}, {'Item': 'D'}), ({'Item': 'C'}, {'Item': 'D'}), ({'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}), ({'Item': 'A'}, {'Item': 'B'}, {'Item': 'D'}), ({'Item': 'A'}, {'Item': 'C'}, {'Item': 'D'}), ({'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}), ({'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'})]
combinationsList = [list(i) for i in allCombinations] # Make into a list so new dict-key can be saved
# combinationsList = [[{'Item': 'A'}, {'Item': 'B'}], [{'Item': 'A'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}], [{'Item': 'B'}, {'Item': 'D'}], [{'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]]
for item in combinationsList:
for i in range(0, len(item) - 1):
item[i]["newkey"] = random.random()
# i want:
# combinationsList = [[{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'B'}], [{'Item': 'A'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}], [{'Item': 'B'}, {'Item': 'D'}], [{'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]]
# but what i get is
# combinationsList = [[{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'B'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'C'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}], [{'Item': 'B'}, {'Item': 'D'}], [{'Item': 'C'}, {'Item': 'D'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'B'}, {'Item': 'D'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]]
print(combinationsList)
exit() # exit only for demo purposes
"""
# What's really odd is if i explicitly make combinationsList, run the same code, it works:
combinationsList = [[{'Item': 'A'}, {'Item': 'B'}], [{'Item': 'A'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}], [{'Item': 'B'}, {'Item': 'D'}], [{'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]]
for item in combinationsList:
for i in range(0, len(item) - 1):
item[i]["newkey"] = random.random()
# works perfectly
print(combinationsList)
exit() # exit only for demo purposes
"""
您的元组包含 对 seq
词典的引用;它们不是那些词典的副本。您必须明确地从每个词典创建新词典:
for i in range(2, len(seq) + 1):
combinationTuple = [tuple(d.copy() for d in c) for c in itertools.combinations(seq, i)]
allCombinations += combinationTuple
仅仅因为元组是不可变的并不意味着它们的内容仍然不能共享。
演示:
>>> import itertools
>>> seq = [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]
>>> not_copied = list(itertools.combinations(seq, 2))
>>> not_copied[0]
({'Item': 'A'}, {'Item': 'B'})
>>> not_copied[0][0]['foo'] = 'bar'
>>> seq
[{'foo': 'bar', 'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]
>>> copied = [tuple(d.copy() for d in c) for c in itertools.combinations(seq, 2)]
>>> copied[0]
({'foo': 'bar', 'Item': 'A'}, {'Item': 'B'})
>>> del copied[0][0]['foo']
>>> seq
[{'foo': 'bar', 'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]
>>> not_copied[0][0] is seq[0]
True
>>> copied[0][0] is seq[0]
False
当我在列表(从元组创建)中的字典上创建新字典值时,字典值更新所有相似的字典条目,而不是我想要的单个条目:
import itertools
import random
seq = [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]
# Create combinations of ABCD -> AB, AC, AD, BA, BB, BC [...] ABD [...] ABCD
allCombinations = []
for i in range(2, len(seq) + 1):
combinationTuple = list(itertools.combinations(seq, i)) # Produces tuples (immutable) of dictionaries
allCombinations += combinationTuple
# allCombinations = [({'Item': 'A'}, {'Item': 'B'}), ({'Item': 'A'}, {'Item': 'C'}), ({'Item': 'A'}, {'Item': 'D'}), ({'Item': 'B'}, {'Item': 'C'}), ({'Item': 'B'}, {'Item': 'D'}), ({'Item': 'C'}, {'Item': 'D'}), ({'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}), ({'Item': 'A'}, {'Item': 'B'}, {'Item': 'D'}), ({'Item': 'A'}, {'Item': 'C'}, {'Item': 'D'}), ({'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}), ({'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'})]
combinationsList = [list(i) for i in allCombinations] # Make into a list so new dict-key can be saved
# combinationsList = [[{'Item': 'A'}, {'Item': 'B'}], [{'Item': 'A'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}], [{'Item': 'B'}, {'Item': 'D'}], [{'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]]
for item in combinationsList:
for i in range(0, len(item) - 1):
item[i]["newkey"] = random.random()
# i want:
# combinationsList = [[{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'B'}], [{'Item': 'A'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}], [{'Item': 'B'}, {'Item': 'D'}], [{'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]]
# but what i get is
# combinationsList = [[{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'B'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'C'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}], [{'Item': 'B'}, {'Item': 'D'}], [{'Item': 'C'}, {'Item': 'D'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'B'}, {'Item': 'D'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}], [{'newkey': 0.06184604397709914, 'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]]
print(combinationsList)
exit() # exit only for demo purposes
"""
# What's really odd is if i explicitly make combinationsList, run the same code, it works:
combinationsList = [[{'Item': 'A'}, {'Item': 'B'}], [{'Item': 'A'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}], [{'Item': 'B'}, {'Item': 'D'}], [{'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}], [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]]
for item in combinationsList:
for i in range(0, len(item) - 1):
item[i]["newkey"] = random.random()
# works perfectly
print(combinationsList)
exit() # exit only for demo purposes
"""
您的元组包含 对 seq
词典的引用;它们不是那些词典的副本。您必须明确地从每个词典创建新词典:
for i in range(2, len(seq) + 1):
combinationTuple = [tuple(d.copy() for d in c) for c in itertools.combinations(seq, i)]
allCombinations += combinationTuple
仅仅因为元组是不可变的并不意味着它们的内容仍然不能共享。
演示:
>>> import itertools
>>> seq = [{'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]
>>> not_copied = list(itertools.combinations(seq, 2))
>>> not_copied[0]
({'Item': 'A'}, {'Item': 'B'})
>>> not_copied[0][0]['foo'] = 'bar'
>>> seq
[{'foo': 'bar', 'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]
>>> copied = [tuple(d.copy() for d in c) for c in itertools.combinations(seq, 2)]
>>> copied[0]
({'foo': 'bar', 'Item': 'A'}, {'Item': 'B'})
>>> del copied[0][0]['foo']
>>> seq
[{'foo': 'bar', 'Item': 'A'}, {'Item': 'B'}, {'Item': 'C'}, {'Item': 'D'}]
>>> not_copied[0][0] is seq[0]
True
>>> copied[0][0] is seq[0]
False