I'm new to python and am just learning about immutable and mutable objects (I've never came across this before with my limited coding experience in MATLAB and C#).
I wanted to know why, if dicts in python are mutable, does editing a dict contained in a second dict not change the second dict?
Here is an example, where a dict (batman) is added to a dict of superhero names (super_hero_names). When batman is later changed, it isn't reflected in the superhero names dict. This makes sense to me if dicts were immutable like strings, but they are mutable so why is this happening?
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'}
The problem in your code is that strings are immutable: you cannot modify the string 'Bruce'
into 'Bruce Wayne'
. You replace it and the reference is gone. If you use a mutable object as value, you can achieve the desired result:
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 and Python often have a very similar syntax. Ruby strings are mutable, so your code would work in Ruby with very few modifications:
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"}