In [1]:
x = [ [2] * 3 ] * 3
x[0][0] = "ZZ"
print(*x, sep="\n")
What I wanted to do was build a nested list, x is supposed to look like:
[[2, 2, 2],
[2, 2, 2],
[2, 2, 2]]
And then I wanted to change the value at index [0][0] but notice that instead of a single value changing the first item in every list changes. I wanted:
[["ZZ", 2, 2],
[ 2, 2, 2],
[ 2, 2, 2]]
But I got:
[["ZZ", 2, 2],
["ZZ", 2, 2],
["ZZ", 2, 2]]
Wierd right?
Your homework for this week it to search google for an awnser to this problem. Why doesn't X behave like I want it too and what to I need to make it work?
I know for a fact the awnser is on stackoverflow already (and probably hundreds of other websites too), so this is a test of your googling skills:
What search query is likely to return the information you need?
This excerise is a really useful I think. Through-out your programming carrear you are going to stumped on tough questions. In many cases, the fastest way to solve your issue is going to be google search. BUT to get the most out of a search engine is going to require you to carefully think about your problem and what query might contain the awnser.
Google to the rescue! Okay so let's think about this problem a little bit; what "buzz words” might we need to feed google in order to get the answer we want?
Lets try...
Python
Err...yeah, I think we are going to need to be a bit more specific than that.
Python nested list
This search is a bit better, I mean, from the context alone Google has probably figured out that we are not interested in snakes! But again, still probably not specific enough.
Python nested list sublist assignment
This query seems decent right? It seems pretty descriptive of the problem, afterall.
Lets run it!
Google Search (15th June 2017)
The third hit sounds promising, lets go there and see.
...And sure enough, it sounds like someone is dealing with the EXACT ISSUE we had. The top-voted reply not only explains the issue but also the fix.
Basically, the issue is that when you write [ [0]*3] *3 ] we are actually storing a reference to the same list.
In [3]:
out=[[0]*3]*3
print( id(out[0]) )
print( id(out[1]) ) # want to know what "id" is? Why not read the documentation!
To see what's happening lets rewrite the code to make the issue even clearer:
In [4]:
a = [2] * 3
x = [a] * 3
print(*x, sep="\n")
print()
a[0] = "ZZ"
print(*x, sep="\n")
So basically the issue is was that when we write [2]*3 and try to add it to a list python isn't making three separate lists, rather, its adding the same list three times!
The fix then, we need to make sure Python knows we want three separate lists, which we can do with a for loop:
In [5]:
x = []
for i in range(3):
x.append([2]*3)
print(*x, sep="\n")
print()
x[0][0] = "ZZ"
print(*x, sep="\n")
In [ ]: