1

In Python 3.0, if I run the following code for a Hangman game

secretWord = list("Apple")
compareWord = secretWord
print("".join(secretWord))

for (index , alphabet) in enumerate(secretWord):
    compareWord[index] = "_"

print("".join(secretWord))

The result is

Apple
_____

Why did it change the secret word? I wanted to only modify compareWord so that it went from secretWord to having underscores instead.

Mazdak
  • 105,000
  • 18
  • 159
  • 188
user1936752
  • 756
  • 1
  • 9
  • 25

2 Answers2

2

Lists are mutable objects and in following line you are creatign another copy of secretWord with name compareWord:

compareWord = secretWord

Therefore when you changes the compareWord you are changing the main object which is what that secretWord is pointing to.

For getting ride of that problem you need to pass a copy of your list, if it's a 1d list you can use a shallow copy otherwise use copy.deepcopy.

compareWord = secretWord[:]  # shallow copy
Mazdak
  • 105,000
  • 18
  • 159
  • 188
2

This happens because both secretWord and compareWord point to the same list.

The first line of code creates a new list from the string Apple, and assigns that list to secretWord. The second line assigns this list to compareWord - both variables now point to the same list! The for-loop changes each item in the list to an underscore. When printing this list it rightly shows 5 underscores.

If you move the print("".join(secretWord)) call to after the loop, you will see that the output of that call has also changed to the 5 underscores.

A simple way to fix this is to assign a copy of the list to compareWord (that is, a new list but with the same contents of the old one). For exmaple:

  • Slicing: compareWord = secretWord[:]
  • New list call: compareWord = List(secretWord)

For some detailed information on how to clone a list in Python, see How to clone or copy a list?

For some intro on Python and lists, see https://developers.google.com/edu/python/lists, this also nicely shows the problem your encountering.

Community
  • 1
  • 1
vendero
  • 36
  • 2