Python Forum

Full Version: Unexpected behavior appending to a List of Dictionaries
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi all
I am getting unexpected behavior when appending a Dictionary to a List of Dictionaries.
If I define the dictionary variable in one go, and then append it to the list - it is successful
If I define the dictionary variable step by step with a single key and value each time and then append it to the list, it does not work as expected. In addition, defining the dictionary variable step by step seems to somehow change the List of Dictionaries entry too.
Could you please help advise what I am doing wrong in the second case. This is my first post, so please let me know if I am not posting correctly, too.
Thank you

The code is :

print("this works")
aliens = []
single_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
aliens.append(single_alien)
single_alien = {'color': 'blue', 'points': 6, 'speed': 'medium'}
aliens.append(single_alien)
single_alien = {'color': 'orange', 'points': 7, 'speed': 'fast'}
aliens.append(single_alien)
single_alien = {'color': 'grey', 'points': 8, 'speed': 'ultraslow'}
aliens.append(single_alien)
for alien in aliens:
        print(alien)


print("this doesn't work")
aliens = []
single_alien['color'] = 'green'
single_alien['points'] =  5
single_alien['speed'] = 'slow'
aliens.append(single_alien)

single_alien['color'] = 'blue'
single_alien['points'] =  6
single_alien['speed'] = 'medium'
aliens.append(single_alien)

single_alien['color'] = 'orange'
single_alien['points'] =  7
single_alien['speed'] = 'fast'
aliens.append(single_alien)

single_alien['color'] = 'grey'
single_alien['points'] =  8
single_alien['speed'] = 'ultraslow'
aliens.append(single_alien)

for alien in aliens:
        print(alien)
The output from the two scenarios is :

this works
{'color': 'green', 'points': 5, 'speed': 'slow'}
{'color': 'blue', 'points': 6, 'speed': 'medium'}
{'color': 'orange', 'points': 7, 'speed': 'fast'}
{'color': 'grey', 'points': 8, 'speed': 'ultraslow'}
this doesn't work
{'color': 'grey', 'points': 8, 'speed': 'ultraslow'}
{'color': 'grey', 'points': 8, 'speed': 'ultraslow'}
{'color': 'grey', 'points': 8, 'speed': 'ultraslow'}
{'color': 'grey', 'points': 8, 'speed': 'ultraslow'}
You need to read about mutable and immutable objects in Python.

Dictionaries are mutable objects, so they could be changed in-place:

single_alien = {'color': 'grey', 'points': 8, 'speed': 'ultraslow'}

print(id(single_alien)) # print unique identifier of the object single_alien
# assume, that returned by `id` value is 12345

single_alien['color'] = 'green'
single_alien['points'] =  5
single_alien['speed'] = 'slow'

print(id(single_alien)) # lets print id again, after changes... 
# it is 12345! # So, the object was changed in-place, this is mutability...
aliens.append(single_alien)
 
single_alien['color'] = 'blue'
single_alien['points'] =  6
single_alien['speed'] = 'medium'

print(id(single_alien))
# it is still...  12345!
aliens.append(single_alien)
So, each time you appending single_alien to aliens, Python just duplicates references to the object single_alien;

for alien in aliens:
 print(id(alien))
 # will give the same values 
Each time you assigning a new dictionary to the single_alien,
internally, a new python object is created. You can check it with id.
ids will be different...

single_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
print(id(single_alien))
# eg. 123456
aliens.append(single_alien)

single_alien = {'color': 'blue', 'points': 6, 'speed': 'medium'}
print(id(single_alien))
# eg. 123234  123234!=123456, i.e. another object!
aliens.append(single_alien)
(Apr-03-2018, 12:39 AM)scidam Wrote: [ -> ]You need to read about mutable and immutable objects in Python.
Dictionaries are mutable objects, so they could be changed in-place:

Thank you very much, Tim