python 字典列表只存储每次迭代中最后追加的值

vmdwslir  于 2023-02-21  发布在  Python
关注(0)|答案(4)|浏览(146)

我有这样的字典列表:

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

我想创建一个新的字典列表(word_db2),其中MylistOfdict中的每个字典都有3个字典。除了MylistOfdict的键和值之外,每个字典都应该有值为类型1、类型2、类型3的“Card Type”键和值为增量的“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': 'surveillance', 'Word No': 1, 'Card Type': 'Type 1', 'Card Key': 1}
{'Word': 'surveillance', 'Word No': 1, 'Card Type': 'Type 2', 'Card Key': 2}
{'Word': 'surveillance', 'Word No': 1, 'Card Type': 'Type 3', 'Card Key': 3}
{'Word': 'equivocal', 'Word No': 2, 'Card Type': 'Type 1', 'Card Key': 4}
{'Word': 'equivocal', 'Word No': 2, 'Card Type': 'Type 2', 'Card Key': 5}
{'Word': 'equivocal', 'Word No': 2, 'Card Type': 'Type 3', 'Card Key': 6}

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

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

gzjq41n41#

让我们一步一步地回顾循环体逻辑:
1.记下其中一条
1.修改它
1.将其附加到列表的末尾
因此,您忽略了一个关键点,即修改并追加了在第一步中选择的同一个对象,在代码片段的末尾,word_db2包含6个对象引用,但只有两个是唯一的,因此,输出显示的是类似的行。
您可以在修改和追加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包含其他可变对象(如嵌套dict),则应创建一个深层副本

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
ifsvaxew

ifsvaxew2#

当你把字典追加到列表中时,会追加一个对原始对象本身的引用,所以,你现在只是在每次内循环迭代中修改现有对象的键和值,所以最后写入的值是唯一保留的。
要完成所需的操作,需要在内循环的每次迭代中创建一个新的dictionary对象。对于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
agyaoht7

agyaoht73#

不要使用相同的法令,复制它们:

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
vuv7lop3

vuv7lop34#

使用deepcopy,发生的事情是你的append调用只是把一个引用附加到原始对象上。

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)

相关问题