1

When I run this,

key=[[0, 0, 0], [1, 0, 0], [0, 1, 1]]
key_=[[0, 0, 0], [1, 0, 0], [0, 1, 1]]
m=3
for i_ in range(1,m+1):
    for j_ in range(1,m+1):
        key[j_-1][m+1-i_-1]=key_[i_-1][j_-1]
print(key,key_,sep='\n')

I got this:

>>> [[0, 1, 0], [1, 0, 0], [1, 0, 0]]
[[0, 0, 0], [1, 0, 0], [0, 1, 1]]

However, when I changed only the second line,

key=[[0, 0, 0], [1, 0, 0], [0, 1, 1]]
key_=key
m=3
for i_ in range(1,m+1):
    for j_ in range(1,m+1):
        key[j_-1][m+1-i_-1]=key_[i_-1][j_-1]
print(key,key_,sep='\n')

I got this:

>>> [[0, 1, 0], [0, 0, 0], [0, 0, 0]]
[[0, 1, 0], [0, 0, 0], [0, 0, 0]]

Why do the two codes have different results? In my opinion, they should be same. Why the different parts make different results?

mr NAE
  • 3,144
  • 1
  • 15
  • 35
Heyday
  • 13
  • 2

1 Answers1

0

In Python, variables which contain lists are more like pointers. When you say key_=key, you're telling Python to use the same list in both cases, not a copy. If you want a copy of the original list, use key_=[x.copy() for x in key]. This will copy the contents of each item (which are lists) in key.

Examples:

Make two lists which contain 1, 2 and 3

>>> my_list = [1,2,3]
>>> my_list
[1, 2, 3]
>>> my_list2 = my_list
>>> my_list2
[1, 2, 3]

Now let's edit the value of the original list...

>>> my_list[0] = 10
>>> my_list
[10, 2, 3]
>>> my_list2
[10, 2, 3]

The changes are copied because my_list and my_list2 are the same, not just a copy of it.

Let's change my_list2:

>>> my_list2[1] = 20
>>> my_list2
[10, 20, 3]
>>> my_list
[10, 20, 3]

And once again, the values are updated between the two as they both point to the same list.

Now let's see what happens if we use the copy method:

>>> my_list_copy = my_list.copy()
>>> my_list_copy
[10, 20, 3]
>>> my_list[0] = 1
>>> my_list
[1, 20, 3]
>>> my_list_copy
[10, 20, 3]

And so we can see that the two lists start with the same contents, but are different.

Using the is operator, we can also see this difference between the 3 list variables:

>>> my_list is my_list2
True
>>> my_list is my_list_copy
False
>>> 

EDIT:

key is a list containing lists as items. When the copy method is called, only the outer list is copied, so the actual items in both lists (ie the sub-lists) are identical. To copy these by value rather than effectively by reference, we can use a simple list comprehension:

key_=[x.copy() for x in key]

This code copies each item in key by value, and creates a new list with these as items.

The output using this is

[[0, 1, 0], [1, 0, 0], [1, 0, 0]]
[[0, 0, 0], [1, 0, 0], [0, 1, 1]]
Ed Ward
  • 2,333
  • 2
  • 10
  • 16