如果 python 中的字典是可变的,为什么编辑包含在第二个字典中的字典不会更改第二个字典?
If dicts in python are mutable, why does editing a dict contained in a second dict not change the second dict?
我是 python 的新手,我只是在学习不可变对象和可变对象(我以前在 MATLAB 和 C# 方面的编码经验有限,因此从未遇到过这个问题)。
我想知道为什么,如果 python 中的字典是可变的,编辑第二个字典中包含的字典不会更改第二个字典吗?
这是一个例子,其中一个字典(蝙蝠侠)被添加到一个超级英雄名字的字典中(super_hero_names)。当蝙蝠侠后来被改变时,它并没有反映在超级英雄的名字字典中。如果字典像字符串一样不可变,这对我来说很有意义,但它们是可变的,那么为什么会这样?
super_hero_names = {
'Superman' : 'Clark Kent',
'Spiderman' : 'Peter Parker'
}
batman = {'Batman' : 'Bruce'}
super_hero_names.update(batman)
batman['Batman'] = 'Bruce Wayne' # (edited)
print(super_hero_names)
# Output: {'Superman': 'Clark Kent', 'Spiderman': 'Peter Parker', 'Batman': 'Bruce'}
每次创建字典batman
,实际上是在创建一个字典并将其赋值给变量batman
我相信你想做的是:
super_hero_names = {
'Superman' : 'Clark Kent',
'Spiderman' : 'Peter Parker'}
batman = {'Batman' : 'Bruce'}
super_hero_names.update(batman)
super_hero_names['Batman'] = 'Bruce Wayne'
print(super_hero_names)
这种情况下的输出将是:
{'Superman': 'Clark Kent', 'Spiderman': 'Peter Parker', 'Batman': 'Bruce Wayne'}
我希望这能解释你的问题。当您更新字典时,它会使用另一个字典的值更新字典,它正在合并。但是,当您将一个字典插入另一个字典时,存在可变性
super_hero_names = {
'Superman' : 'Clark Kent',
'Spiderman' : 'Peter Parker'
}
batman = {'Batman' : 'Bruce'}
super_hero_names['new'] = batman
print(super_hero_names)
batman['Batman'] = 'Bruce Wayne'
print(super_hero_names)
batman = {'Batman' : 'Bruce Wayne'}
print(super_hero_names)
输出
{'Spiderman': 'Peter Parker', 'new': {'Batman': 'Bruce'}, 'Superman': 'Clark Kent'}
{'Spiderman': 'Peter Parker', 'new': {'Batman': 'Bruce Wayne'}, 'Superman': 'Clark Kent'}
{'Spiderman': 'Peter Parker', 'new': {'Batman': 'Bruce Wayne'}, 'Superman': 'Clark Kent'}
在这种情况下,update()
表现如下:
for key, value in batman.items():
super_hero_names[key] = value
这里,super_hero_names.update(batman)
首先检查super_hero_names
是否有'Batman'键。如果存在,它会覆盖(或更新)该值。如果不是,它会创建 'Batman' 并 将值 分配给键。
已添加:
这是一个示例代码。我没有使用字典作为数据容器,而是使用列表来保存多个超人字典。正如你所说,字典是可变的,所以 update 方法修改 super_hero_names
.
列表中的内容
superman = {'Superman' : 'Clark Kent'}
spiderman = {'Spiderman' : 'Peter Parker'}
super_hero_names = [
superman,
spiderman
]
batman = {'Batman' : 'Bruce'}
super_hero_names.append(batman)
print(super_hero_names)
# [{'Superman': 'Clark Kent'}, {'Spiderman': 'Peter Parker'}, {'Batman': 'Bruce'}]
batman.update({'Batman': 'test'})
print(super_hero_names)
# [{'Superman': 'Clark Kent'}, {'Spiderman': 'Peter Parker'}, {'Batman': 'test'}]
你可以通过将名称存储在列表中来实现你想要的,但是由于额外的间接层,它会使代码更加混乱和效率降低。
super_hero_names = {
'Superman' : ['Clark Kent'],
'Spiderman' : ['Peter Parker'],
}
batman = {'Batman' : ['Bruce']}
super_hero_names.update(batman)
batman['Batman'][0] = 'Bruce Wayne'
print(super_hero_names)
输出
{'Superman': ['Clark Kent'], 'Spiderman': ['Peter Parker'], 'Batman': ['Bruce Wayne']}
我们也可以使用
进行更新
batman['Batman'][0] += ' Wayne'
可变名称
您的代码中的问题是字符串是不可变的:您不能将字符串 'Bruce'
修改为 'Bruce Wayne'
。你更换它,参考就消失了。如果使用可变对象作为值,可以达到预期的效果:
class Person:
def __init__(self, name):
self.name = name
def __repr__(self):
return repr(self.name)
super_hero_names = {
'Superman': Person('Clark Kent'),
'Spiderman': Person('Peter Parker')
}
bruce = Person('Bruce')
batman = {'Batman': bruce}
super_hero_names.update(batman)
bruce.name = 'Bruce Wayne'
print(super_hero_names)
# {'Superman': 'Clark Kent', 'Spiderman': 'Peter Parker', 'Batman': 'Bruce Wayne'}
您在 Ruby
中的示例
Ruby 和 Python 通常具有非常相似的语法。 Ruby 字符串是可变的,因此您的代码只需很少的修改就可以在 Ruby 中运行:
super_hero_names = {
'Superman' => 'Clark Kent',
'Spiderman' => 'Peter Parker'
}
batman = {'Batman' => 'Bruce'}
super_hero_names.update(batman)
batman['Batman'] << ' Wayne' # Mutates the string, doesn't replace it!
print(super_hero_names)
# {"Superman"=>"Clark Kent", "Spiderman"=>"Peter Parker", "Batman"=>"Bruce Wayne"}
我是 python 的新手,我只是在学习不可变对象和可变对象(我以前在 MATLAB 和 C# 方面的编码经验有限,因此从未遇到过这个问题)。
我想知道为什么,如果 python 中的字典是可变的,编辑第二个字典中包含的字典不会更改第二个字典吗?
这是一个例子,其中一个字典(蝙蝠侠)被添加到一个超级英雄名字的字典中(super_hero_names)。当蝙蝠侠后来被改变时,它并没有反映在超级英雄的名字字典中。如果字典像字符串一样不可变,这对我来说很有意义,但它们是可变的,那么为什么会这样?
super_hero_names = {
'Superman' : 'Clark Kent',
'Spiderman' : 'Peter Parker'
}
batman = {'Batman' : 'Bruce'}
super_hero_names.update(batman)
batman['Batman'] = 'Bruce Wayne' # (edited)
print(super_hero_names)
# Output: {'Superman': 'Clark Kent', 'Spiderman': 'Peter Parker', 'Batman': 'Bruce'}
每次创建字典batman
,实际上是在创建一个字典并将其赋值给变量batman
我相信你想做的是:
super_hero_names = {
'Superman' : 'Clark Kent',
'Spiderman' : 'Peter Parker'}
batman = {'Batman' : 'Bruce'}
super_hero_names.update(batman)
super_hero_names['Batman'] = 'Bruce Wayne'
print(super_hero_names)
这种情况下的输出将是:
{'Superman': 'Clark Kent', 'Spiderman': 'Peter Parker', 'Batman': 'Bruce Wayne'}
我希望这能解释你的问题。当您更新字典时,它会使用另一个字典的值更新字典,它正在合并。但是,当您将一个字典插入另一个字典时,存在可变性
super_hero_names = {
'Superman' : 'Clark Kent',
'Spiderman' : 'Peter Parker'
}
batman = {'Batman' : 'Bruce'}
super_hero_names['new'] = batman
print(super_hero_names)
batman['Batman'] = 'Bruce Wayne'
print(super_hero_names)
batman = {'Batman' : 'Bruce Wayne'}
print(super_hero_names)
输出
{'Spiderman': 'Peter Parker', 'new': {'Batman': 'Bruce'}, 'Superman': 'Clark Kent'}
{'Spiderman': 'Peter Parker', 'new': {'Batman': 'Bruce Wayne'}, 'Superman': 'Clark Kent'}
{'Spiderman': 'Peter Parker', 'new': {'Batman': 'Bruce Wayne'}, 'Superman': 'Clark Kent'}
在这种情况下,update()
表现如下:
for key, value in batman.items():
super_hero_names[key] = value
这里,super_hero_names.update(batman)
首先检查super_hero_names
是否有'Batman'键。如果存在,它会覆盖(或更新)该值。如果不是,它会创建 'Batman' 并 将值 分配给键。
已添加:
这是一个示例代码。我没有使用字典作为数据容器,而是使用列表来保存多个超人字典。正如你所说,字典是可变的,所以 update 方法修改 super_hero_names
.
superman = {'Superman' : 'Clark Kent'}
spiderman = {'Spiderman' : 'Peter Parker'}
super_hero_names = [
superman,
spiderman
]
batman = {'Batman' : 'Bruce'}
super_hero_names.append(batman)
print(super_hero_names)
# [{'Superman': 'Clark Kent'}, {'Spiderman': 'Peter Parker'}, {'Batman': 'Bruce'}]
batman.update({'Batman': 'test'})
print(super_hero_names)
# [{'Superman': 'Clark Kent'}, {'Spiderman': 'Peter Parker'}, {'Batman': 'test'}]
你可以通过将名称存储在列表中来实现你想要的,但是由于额外的间接层,它会使代码更加混乱和效率降低。
super_hero_names = {
'Superman' : ['Clark Kent'],
'Spiderman' : ['Peter Parker'],
}
batman = {'Batman' : ['Bruce']}
super_hero_names.update(batman)
batman['Batman'][0] = 'Bruce Wayne'
print(super_hero_names)
输出
{'Superman': ['Clark Kent'], 'Spiderman': ['Peter Parker'], 'Batman': ['Bruce Wayne']}
我们也可以使用
进行更新batman['Batman'][0] += ' Wayne'
可变名称
您的代码中的问题是字符串是不可变的:您不能将字符串 'Bruce'
修改为 'Bruce Wayne'
。你更换它,参考就消失了。如果使用可变对象作为值,可以达到预期的效果:
class Person:
def __init__(self, name):
self.name = name
def __repr__(self):
return repr(self.name)
super_hero_names = {
'Superman': Person('Clark Kent'),
'Spiderman': Person('Peter Parker')
}
bruce = Person('Bruce')
batman = {'Batman': bruce}
super_hero_names.update(batman)
bruce.name = 'Bruce Wayne'
print(super_hero_names)
# {'Superman': 'Clark Kent', 'Spiderman': 'Peter Parker', 'Batman': 'Bruce Wayne'}
您在 Ruby
中的示例Ruby 和 Python 通常具有非常相似的语法。 Ruby 字符串是可变的,因此您的代码只需很少的修改就可以在 Ruby 中运行:
super_hero_names = {
'Superman' => 'Clark Kent',
'Spiderman' => 'Peter Parker'
}
batman = {'Batman' => 'Bruce'}
super_hero_names.update(batman)
batman['Batman'] << ' Wayne' # Mutates the string, doesn't replace it!
print(super_hero_names)
# {"Superman"=>"Clark Kent", "Spiderman"=>"Peter Parker", "Batman"=>"Bruce Wayne"}