Python:字典存储列表仅在每次迭代中都是最后一个附加值

时间:2017-10-19 17:01:17

标签: python list dictionary

我有这个字典列表:

MylistOfdict = [{'Word': 'surveillance',
  'Word No': 1},
 {'Word': 'equivocal',
  'Word No': 2}]

我想创建一个新的字典列表(word_db2),其中包含MylistOfdict中每个字典的3个字典。除了MylistOfdict的键和值之外,这些词典中的每一个都应该具有'卡类型'键值为Type 1,Type 2,Type 3和' Card Key'具有增量值的键

代码:

word_db2 = []

key = 1
for i in MylistOfdict:
    for j in range(1, 4):
        i['Card Type'] = 'Type '+str(j)
        i['Card Key'] = key
        print(i)

        word_db2.append(i)
        key += 1

输出:

{'Word No': 1, 'Card Key': 1, 'Word': 'surveillance', 'Card Type': 'Type 1'}
{'Word No': 1, 'Card Key': 2, 'Word': 'surveillance', 'Card Type': 'Type 2'}
{'Word No': 1, 'Card Key': 3, 'Word': 'surveillance', 'Card Type': 'Type 3'}
{'Word No': 2, 'Card Key': 4, 'Word': 'equivocal', 'Card Type': 'Type 1'}
{'Word No': 2, 'Card Key': 5, 'Word': 'equivocal', 'Card Type': 'Type 2'}
{'Word No': 2, 'Card Key': 6, 'Word': 'equivocal', 'Card Type': 'Type 3'}

此输出正确,但word_db2仅存储每次迭代中的最后一个附加值

print(word_db2)

输出:

[{'Card Key': 3, 'Card Type': 'Type 3', 'Word': 'surveillance', 'Word No': 1},
 {'Card Key': 3, 'Card Type': 'Type 3', 'Word': 'surveillance', 'Word No': 1},
 {'Card Key': 3, 'Card Type': 'Type 3', 'Word': 'surveillance', 'Word No': 1},
 {'Card Key': 6, 'Card Type': 'Type 3', 'Word': 'equivocal', 'Word No': 2},
 {'Card Key': 6, 'Card Type': 'Type 3', 'Word': 'equivocal', 'Word No': 2},
 {'Card Key': 6, 'Card Type': 'Type 3', 'Word': 'equivocal', 'Word No': 2}]

4 个答案:

答案 0 :(得分:3)

让我们一步一步地检查循环体逻辑:

  1. 采取其中一个词汇
  2. 修改
  3. 将其附加到列表的末尾
  4. 因此,您错过的关键点是您修改并附加在第一步中选择的同一对象。在代码段word_db2的末尾包含六个对象引用,但只有两个唯一。结果,输出显示类似的行。

    您可以在修改和附加dict之前制作一个浅拷贝

    for j in range(1, 4):
        i = dict(i)
        i['Card Type'] = 'Type '+str(j)
        i['Card Key'] = key
        print(i)
    
        word_db2.append(i)
        key += 1
    

    进一步说明,如果dict包含其他可变对象(如嵌套dicts),则应创建深层复制

    import copy
    old_dict = {'a': [1, 2, 3], 'b': [4, 5, 6]}
    new_dict = copy.deepcopy(old_dict)
    old_dict['a'][1] = 7
    new_dict['a'][1] # 2
    

答案 1 :(得分:2)

将字典附加到列表时,会附加对原始对象本身的引用。因此,您目前只是在内部循环的每次迭代中修改现有对象的键和值,因此最后写入的值是唯一持久的值。

要执行您需要的操作,您需要在内部循环的每次迭代中创建一个新的字典对象。对于MylistOfdict中显示的词典,简单的词典理解就可以了。但是如果您有更复杂的词典,请使用copy模块的deepcopy方法。

MylistOfdict = [{'Word': 'surveillance', 'Word No': 1}, 
                {'Word': 'equivocal', 'Word No': 2}]
word_db2 = []

key = 1
for i in MylistOfdict:
    for j in range(1, 4):
        # Creating a new dictionary object and copying keys and values from i
        new_dict = {k: v for k, v in i.items()}
        new_dict['Card Type'] = 'Type '+str(j)
        new_dict['Card Key'] = key

        print(new_dict)

        word_db2.append(new_dict)
        key += 1

答案 2 :(得分:1)

不要使用相同的词典,复制它们:

word_db2 = []

key = 1
for i in MylistOfdict:
    for j in range(1, 4):
        i = dict(i)
        i['Card Type'] = 'Type '+str(j)
        i['Card Key'] = key
        print(i)

        word_db2.append(i)
        key += 1

答案 3 :(得分:-1)

使用deepcopy。发生的事情是你的追加调用只是附加对原始对象的引用。

from copy import deepcopy

my_list_of_dict = [{'Word': 'surveillance',
                    'Word No': 1},
                   {'Word': 'equivocal',
                    'Word No': 2}]
word_db2 = []

key = 1
for i in my_list_of_dict:
    for j in range(1, 4):
        i['Card Type'] = 'Type ' + str(j)
        i['Card Key'] = key
        print(i)
        word_db2.append(deepcopy(i))
        key += 1


for i in word_db2:
    print(i)