【问题标题】:Dictionary value in Dictionary list created from tuple doesn't update correctly从元组创建的字典列表中的字典值未正确更新
【发布时间】:2015-07-15 02:54:18
【问题描述】:

当我在列表中的字典(从元组创建)上创建新字典值时,字典值会更新所有相似的字典条目,而不是我想要的单个条目:

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
"""

【问题讨论】:

    标签: python python-3.x dictionary iteration tuples


    【解决方案1】:

    您的元组包含对来自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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      • 2017-05-05
      • 2018-11-06
      相关资源
      最近更新 更多