2

I'm self-studying Python using "Python Crash Course", and have been programming most of the code in the book as well as the set questions. There is one example where a list of dictionaries is created, using this code:

# Make an empty list for storing aliens.
aliens = []

# Make 30 green aliens.
for alien_number in range (0,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[0:5]:
    print(alien)
print("...")

This works as expected, producing an initial list of 30 green aliens, and then the first three are modified to be yellow.

However, I was experimenting with the code, and I wondered why the

new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}

line was inside the first for loop (as it seemed to be creating the same thing every time, it seemed redundant to me that it was inside the loop).

Moving it outside (I'll only put the relevant changes, so the second block of code is altered):

# Make 30 green aliens.
new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
for alien_number in range (0,30):
    aliens.append(new_alien)

This produces output that I can't understand - ALL the aliens become yellow - the [0:3] part of the second for loop has no effect - I tried setting it to all sorts of values, and none of the changed the function - they all and up being altered by the second loop.

Could someone explain why this is happening? I'm happy to read an appropriate link if someone can provide one, but I can't think of what to search for that would explain this (as I don't know what's happening, therefore don't know what to look for other than Yellow Aliens!)

martineau
  • 119,623
  • 25
  • 170
  • 301
djaychela
  • 97
  • 2
  • 8
  • 5
    It's happening because you are using the same dictionary for all iterations of the loop, instead of creating a new one each time through the loop. – kindall Jan 05 '17 at 17:38
  • So they are effectively clones of each other and all linked behind the scenes? – djaychela Jan 05 '17 at 17:40
  • 2
    pythonic way of doing this: `aliens = [{'color': 'green', 'points': 5, 'speed': 'slow'} for _ in range(0,30)]` – Jean-François Fabre Jan 05 '17 at 17:40
  • This link might help: https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/ – roganjosh Jan 05 '17 at 17:40
  • 1
    They aren't *clones* -- they are *aliases*. Two human clones are two persons. A person with an alias is just one. Note that you can move the definition outside but then inside the loop have `aliens.append(new_alien.copy())` -- but you need to be aware that `copy()` makes a *shallow* copy -- which is okay here. – John Coleman Jan 05 '17 at 17:41
  • @PatrickHaugh Same issue but not a duplicate since a list of dictionaries is not a list of lists. – John Coleman Jan 05 '17 at 17:43
  • Thanks all, that makes some sense now; I'll attempt to adopt the right terminology (I wasn't aware about aliases). – djaychela Jan 05 '17 at 17:45
  • It's a single object with more than one name. Using the term "aliases" implies that some names are lesser than others, that there is one "real" name and then other names. But all names have the same standing. – kindall Jan 05 '17 at 17:47
  • @kindall "alias" is a standard term in computer science with no implication that one of the aliases is more "real" than the other: https://en.wikipedia.org/wiki/Pointer_aliasing ("In computer programming, aliasing refers to the situation where the same memory location can be accessed using different names.") – John Coleman Jan 05 '17 at 17:56
  • Yes, I'm *sure* that someone with the question being asked is fully conversant with the computer science definition of "alias." :-) – kindall Jan 05 '17 at 18:04
  • 1
    @kindall Perhaps they are just an alias for Donald Knuth and are trolling Stack Overflow. – John Coleman Jan 05 '17 at 18:10

0 Answers0