2

I have a Python code, where I first define two lists, then I make them identical and do the same operation on them after they are identical - but the result is not the same:

test1 = [[[0],[0]]]*2
test2 = [[0]]*2

test2[0] = [[0],[0]]
test2[1] = [[0],[0]]

print 'They are identical?:',test1 == test2 # gives True

# Now that test1 == test2 do the same operation on test list 1 and 2:

test1[0][0] = 2
test2[0][0] = 2

print test1
print test2

This gives

[[2, [0]], [2, [0]]]   # test1
[[2, [0]], [[0], [0]]] # test2

Can somebody explain the difference to me?

Anna Christine
  • 860
  • 1
  • 6
  • 14
  • 4
    they are not identical ... in one you have multiple copies of the same list so if you change one you change them all ... in the other each list is its own and independent of the others – Joran Beasley Jan 20 '14 at 17:59
  • but I do not understand why the line test1 == test2 gives True and when I print them, they are look the same? How can I tell that they are different?? – Anna Christine Jan 20 '14 at 18:01
  • 1
    @AnnaChristine Use `is` operator for checking object's identity. http://stackoverflow.com/a/21230178/846892 – Ashwini Chaudhary Jan 20 '14 at 18:02
  • you need to have an understanding of mutable datatypes and what the times operator does ... basically you just need to study python until you know ...or you can do `test[0] is test[1]` to check – Joran Beasley Jan 20 '14 at 18:02
  • @AshwiniChaudhary: Thank you, the use of IS instead of '==' is part of the really good answer given by val : ) Very helpful. – Anna Christine Jan 20 '14 at 18:06
  • @JoranBeasley Answers as given by val actually make this website appreciated and amazing - it helps people incredibly who are no experts and have no time to 'study python until they now' as you suggest. – Anna Christine Jan 20 '14 at 18:08

2 Answers2

5

If x is a list,

x * 2

Returns two times the same elements from the list.

As lists are passed by references, this means:

>>> A = 2 * [[0]]
>>> B = [[0], [0]]

Will actually not have the same structure: both A[0] and A[1] point to the same list, while B[0] and B[1] point to two different lists.

And indeed, if you try:

>>> A[0] == A[1]
True
>>> A[0] is A[1]
True
>>> A[0].append(1)
>>> A
[[0, 1], [0, 1]]

While:

>>> B[0] == B[1]
True
>>> B[0] is B[1]
False
>>> B[0].append(1)
>>> B
[[0, 1], [0]]
val
  • 8,459
  • 30
  • 34
  • @AnnaChristine: Good answer, except for the "pass by reference" bit. See [How does Python referencing work?](http://stackoverflow.com/q/9724802/208880) for some explanations about variables in Python. – Ethan Furman Jan 20 '14 at 18:20
2

this command

test1 = [[[0],[0]]]*2

is equivalent of this 2:

a = [[0], [0]]
test1 = [a, a]

and then you assigning value to test1[0][0], you are changing value of a list. Of course test[1] changes to, because it is same a list

ndpu
  • 22,225
  • 6
  • 54
  • 69