Afr0 Afr0 - 1 year ago 39
Python Question

Can variables retain previous values in a while loop in python?

My question is when we use a variable in a while loop before changing the variable we have it assigned to (i.e on the Right hand side of the equal to) why does this new variable we supposedly assigned the next variables previous value to change?

I realise the phrasing of my question isn't entirely spot on, so in laymans terms, in my program i'm writing a variable called

before I change the value of
later in the while loop. Here i'm assuming all the code in python runs from top to bottom.

So here's an example of what value predisp holds
so if
disp = ['_','_']

predisp = ['_','_']

which is fine.
But the moment I enter a letter as part of my hangman guess
the value of disp becomes

but the problem is predisp also becomes
which is not what I want. I want it to always have the previous value of
before it undergoes any changes. I'm new to python so I don't really understand how all the variables work, i'm more used to them in C++. Here's the code (it's for a simple hangman game i'm writing).

# Created by Zur-en-Arrh

import random # Useful to select a topic from the file.

# Functions

def same_letter(user_letter, word_to_guess):
if user_letter == word_to_guess:
return True
return False

def wrong_guess(prevdisp,currdisp):
if prevdisp == currdisp:
return True
return False

# Dealing with the file.
filename = input("Which file do you want to play with ")
topics = str(open(filename, 'r').read())
list_of_topics = topics.split() # This is the list that contains the topics randomly selected from the file.
guess_me = list(list_of_topics[random.randint(0, len(list_of_topics) - 1)]) # This is what the user will need to figure out.

# Printing out the Dashes for the user.
disp = []
for i in range(0, len(guess_me)):

# This is just the declaration of the number of wrong guesses. This'll always be 0 at the start of the game.
wrong_guesses = 0

# While loop for game. Also note in hangman, you're only allowed 5 wrong guesses till the body is complete.
while wrong_guesses < 6:
print(' '.join(disp)) # Prints the game in an acceptable format to the user.
predisp = disp
if disp == guess_me: # end the game when the user wins.
user_guess = str(input("Which letter do you think will there be? "))
for i in range(len(guess_me)):
if same_letter(user_guess, guess_me[i]):
disp[i] = user_guess
if wrong_guess(predisp, disp):
wrong_guesses += 1

if wrong_guesses == 6:
print("You got hung! Better luck next time")

if wrong_guesses < 6:
print("Well Done you won the game!")

Answer Source

In Python, variables are references to objects:

disp = []

creates a new list object and makes it accessible by the name disp. What it really does is set disp to point to the newly created list object. The assignment statement

predisp = disp

does the same thing, i.e. it sets predisp to reference the same list object as disp. Thus any change applied to the object that disp points to is also visible in the object that predisp points to - it's the very same object.

One way to avoid this is to create a copy on assignment:

predisp = disp[:]

This can be easily verified by using the id function:

disp = ['_'] * 3
predisp = disp
id(disp), id(predisp)
# same object ids for both variables
=> (4303250784, 4303250784)

predisp = disp[:]
id(disp), id(predisp)
# different object ids
=> (4303250784, 4303043832)