'The python code isn't showing desired output , where is the problem?

My python code is :

new_alien={'color':'green','points':5,'speed':'slow'}
aliens=[]
for alien_number in range(10):
    aliens.append(new_alien)
print(f"total aliens:{len(aliens)}")
print(".......")
print(aliens)

for alien in aliens[:3]:
    if alien['color']=='green':
        alien['color']='yellow'
        alien['points']=10
        alien['speed']='fast'

print(aliens)

And it is showing output like:

total aliens:10
.......
[{'color': 'green', 'points': 5, 'speed': 'slow'}, {'color': 'green', 'points': 5, 'speed': 'slow'}, {'color': 'green', 'points': 5, 'speed': 'slow'}, {'color': 'green', 'points': 5, 'speed': 'slow'}, {'color': 'green', 'points': 5, 'speed': 'slow'}, {'color': 'green', 'points': 5, 'speed': 'slow'}, {'color': 'green', 'points': 5, 'speed': 'slow'}, {'color': 'green', 'points': 5, 'speed': 'slow'}, {'color': 'green', 'points': 5, 'speed': 'slow'}, {'color': 'green', 'points': 5, 'speed': 'slow'}]
[{'color': 'yellow', 'points': 10, 'speed': 'fast'}, {'color': 'yellow', 'points': 10, 'speed': 'fast'}, {'color': 'yellow', 'points': 10, 'speed': 'fast'}, {'color': 'yellow', 'points': 10, 'speed': 'fast'}, {'color': 'yellow', 'points': 10, 'speed': 'fast'}, {'color': 'yellow', 'points': 10, 'speed': 'fast'}, {'color': 'yellow', 'points': 10, 'speed': 'fast'}, {'color': 'yellow', 'points': 10, 'speed': 'fast'}, {'color': 'yellow', 'points': 10, 'speed': 'fast'}, {'color': 'yellow', 'points': 10, 'speed': 'fast'}]

Why is it changing all the elements of the list 'alien' though I looped through only the first 3 elements?



Solution 1:[1]

It's because all the elements in aliens refer to the same variable new_alien

Use new_alien.copy()

new_alien={'color':'green','points':5,'speed':'slow'}
aliens=[]
for alien_number in range(10):
    aliens.append(new_alien.copy())
    
    
print(f"total aliens:{len(aliens)}")
print(".......")
print(aliens)

for alien in aliens[:3]:
    if alien['color']=='green':
        alien['color']='yellow'
        alien['points']=10
        alien['speed']='fast'

print(aliens)

Solution 2:[2]

To properly copy dictionaries, you must use the your_dictionary.copy() method, as shown below:

first_dict = {"world":"hello"}
second_dict = first_dict.copy()
second_dict["world"] = "goodbye"    # After doing this, first_dict is still {"world":"hello"}.

Solution 3:[3]

You can solve by moving the alien definition into the for loop. This will create a new dict in each array entry, rather than all referencing the same thing:

aliens=[]
for alien_number in range(10):
    aliens.append({'color':'green','points':5,'speed':'slow'})
print(f"total aliens:{len(aliens)}")
print(".......")
print(aliens)

Solution 4:[4]

A tricky one.

When a dictionary is stored in memory, and unlike a string, any variable pointing it will be the same dictionary. Try this:

a = {"foo": "bar"}
b = a
a["foo"] = "surprise!"
print(b)

You must use the .copy method of the dict to have diferent aliens:

alien.append(new_alien.copy())

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 BLimitless
Solution 4