嵌套字典改变了我不明白为什么

时间:2016-11-07 19:42:05

标签: python

为什么代码中的这一小改变使得此代码的工作方式不同。我只是学习Python。谁能用简单的方式解释一下? 编辑: 我没有意识到将字典添加到列表中是指向同一个字典而不是实际复制它。我试图在这篇文章之前找到解决方案,但可能在制定我的问题时有点不同,这可能会让有经验的程序员将其视为重复。

输入

# Make an empty list for storing aliens.
aliens = []
# Make 30 green aliens.
for alien_number in range(30):
    new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
    aliens.append(new_alien)

for alien in aliens[0:3]:
    if alien['color'] == 'green':
        alien['color'] = 'yellow'
        alien['speed'] = 'medium'
        alien['points'] = 10
# Show the first 5 aliens:
for alien in aliens[:5]:
    print(alien)
print("...")
# Show how many aliens have been created.
print("Total number of aliens: " + str(len(aliens)))

输出

{'points': 10, 'color': 'yellow', 'speed': 'medium'}
{'points': 10, 'color': 'yellow', 'speed': 'medium'}
{'points': 10, 'color': 'yellow', 'speed': 'medium'}
{'points': 5, 'color': 'green', 'speed': 'slow'}
{'points': 5, 'color': 'green', 'speed': 'slow'}
...
Total number of aliens: 30

现在更改了代码I' ll在第一个for循环

之外初始化字典

输入

# Make an empty list for storing aliens.
aliens = []
# HERE IS THE CHANGE
new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
# Make 30 green aliens.
for alien_number in range(30):
    aliens.append(new_alien)

for alien in aliens[0:3]:
    if alien['color'] == 'green':
        alien['color'] = 'yellow'
        alien['speed'] = 'medium'
        alien['points'] = 10
# Show the first 5 aliens:
for alien in aliens[:5]:
    print(alien)
print("...")
# Show how many aliens have been created.
print("Total number of aliens: " + str(len(aliens)))

输出

{'color': 'yellow', 'points': 10, 'speed': 'medium'}
{'color': 'yellow', 'points': 10, 'speed': 'medium'}
{'color': 'yellow', 'points': 10, 'speed': 'medium'}
{'color': 'yellow', 'points': 10, 'speed': 'medium'}
{'color': 'yellow', 'points': 10, 'speed': 'medium'}   
...
Total number of aliens: 30

为什么第二个是整个字典改变而不只是前3个字典?

1 个答案:

答案 0 :(得分:0)

您的代码的要点是,当您构建第一个字典时,它会创建它并在new_alien变量中存储对它的引用。请注意,这不是对象本身,而是对象的引用。 在第一个片段中,您每次都创建了一个新字典,并将对新字典的引用添加到aliens列表中。在第二种情况下,您只创建了一个字典,并将对该字典的引用五次附加到列表中。 这解释了为什么在第二种情况下你实际上修改了同一个字典。让我们看看这个例子:

dct = {'a': 10, 'b': 20}  # in this moment the dictionary is initialised and a reference to it is stored in the variable dct (let's call this reference 0x01)
# dct = 0x01
lst = []
for i in range(5):
    lst.append(dct)
# at the end of the loop lst = [0x01, 0x01, 0x01, 0x01, 0x01]
lst[0]['a'] = 20  # this means take lst[0] (which is 0x01) interpret it as a dictionary and change the value at `'a'` to 20

因此,此更改将影响您创建的唯一字典,即dct。 在您的第一个代码段的情况下,您创建了5个不同的词典并仅修改了其中的一部分,请参阅此示例:

lst = []
for i in range(5):
    new_dict = {'a': 10, 'b': 20}
    lst.append(new_dict)
# by the end of the loop, lst will have references to five different dictionaries, for instance lst = [0x01, 0x02, 0x03, 0x04, 0x05]

所以在这种情况下修改其中一个条目不会影响其他条目