Python Forum
Unexpected change to a list in a small amount of self-contained code
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Unexpected change to a list in a small amount of self-contained code
#1
I am using Python 3. I am getting an unexpected result: a list is changing, but I do not understand how/where it changes. Here is my code:
def cool(goodlist, letter):
  goodlist.append("foobar")
  goodlist.append(letter)
  newlist = goodlist
  return newlist

alista = []

var1 = cool(alista, "J")
print(var1)
print(alista)
The above program prints out this:
Output:
['foobar', 'J'] ['foobar', 'J'][/font]
I would expect alista to be empty still. Why and what modifies alista?
Reply
#2
moved to homework as this looks like an assignment

key words to look up: def, append, return
Reply
#3
(Mar-13-2020, 02:07 AM)Johno Wrote: Why and what modifies alista?

Short answer: append (rows # 2 and 3 in your code) modifies alista. As of why - you should ask the author why the code is written this way and what the actual intention was.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#4
Long answer.
In older programming languages like C a programmer is very aware of what data is and what a pointer (to data). In higher level programming languages like Pyton most of the implementation in bits and bytes keeps hidden to the programmer. Unfortunately the creators of Python did not succeed in keeping all the internal details hidden. And you just hit such a detail where you need to understand what a pointer is.
When you create a list (alista=[]) then in RAM memory is allocated for this list and the address of this memory location is called a pointer. This pointer is then associated with the identifier (alista).
In your program you pass this pointer as a parameter to a function (var1=cool(alista, "J")). In the function the pointer is associated with a new identifier (goodlist). From this point of view it is clearly understandable that any change to the list will affect both identifiers (alista and goodlist). Furtheron you do a new assignment (newlist=goodlist) and again these two identifiers point to the same list.

So to solve this problem your function should start making it's own copy of the list. The easyest way to do this is:
    newlist = goodlist[:]
"goodlist[:]" is a slice. On both sides of the colon you can give the range: "from:to". A misssing from means the first element and a missing to means the last element. Because the result of slicing is a new list, this new list is allocated in a new location in memory. After that your function should operate on "newlist".
This whole story goes for mutable objects (like lists and dicts). With immutable objects (like strings and integers) you will not encounter these problems, because when you want to change an immutable object in fact new memory is allocated.

I hope this helps you.
Reply
#5
compare output of your code to the one hereunder. Maybe you will be able to decipher the cause yourselves:

def cool(goodlist, letter):
	newlist = []
	newlist.append("foobar")
	newlist.append(letter)
	#newlist = goodlist
	return newlist
 
alista = []
 
var1 = cool(alista, "J")
print(var1)
print(alista)
Output:
['foobar', 'J'] [] [Program finished]
Reply
#6
This reflects that a statement such as newlist=goodlist just creates a pointer to the same list and does not make a copy of the list.

Best 25 minutes to spend to get a real handle on this is Ned Batchelder at Pycon 2015
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Unexpected behavior accessing list elements. tonyflute 2 2,272 Apr-09-2021, 02:36 PM
Last Post: tonyflute
  Change each character of list into an different characters Angry_bird89 1 2,063 Jun-19-2020, 08:29 AM
Last Post: Angry_bird89
  Print the frequency of each coin for the combinations that sum to the amount N Pranav 3 2,553 May-19-2020, 06:16 AM
Last Post: Pranav
  Program that displays the number with the greatest amount of factors ilusmd 3 2,828 Nov-01-2018, 08:28 PM
Last Post: ichabod801
  i need to change the code woiwoi 3 2,974 Nov-28-2017, 05:37 PM
Last Post: nilamo
  Can't figure out small errors in my code? pythonwizard96 1 4,122 Nov-03-2017, 03:29 PM
Last Post: nilamo
  Looping over amount of attempts Beatenberg 4 6,257 Oct-17-2017, 07:47 AM
Last Post: Beatenberg

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020