Editing List of list of list in Python [duplicate] - python

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Changing an element in one list changes multiple lists [duplicate]
(4 answers)
Closed 6 years ago.
I am trying to edit elements in my list of list of list but it is editing multiple elements.
L1 = [[0,0] for count in range(2)]
L2 = [L1 for count in range(2)]
L2[0][0][0] = 5
print(L2)
What I expect is [[[5, 0], [0, 0]], [[0, 0], [0, 0]]]
But what I get is [[[5, 0], [0, 0]], [[5, 0], [0, 0]]]
It seems that I am editing the original list. Can someone explain how to edit a single element or set up nested lists where this effect won't occur.
Many thanks

Don't reuse the variable:
L2 = [[[0,0] for count in range(2)] for count in range(2)]
Then the inner part [[0,0] for count in range(2)] will get recreated every time as a fresh, separate list.

Related

Unexpected behaviour of python matrix (list of lists), assignment is changing whole column [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 4 months ago.
please help me with a question, cause Im getting mad.
I'm creating a 0-matrix, than tried to changed it's first element value to one, but it changes the whole column instead, and I don't get why:
def id_mtrx(n):
m = [[0]*n]*n
m[0][0]=1
return m
here is output:
[[1, 0], [1, 0]]
while I was expecting:
[[1, 0], [0, 0]]
It looks very simple, what can be wrong?
You are creating multiple references to the same list object instead of creating new list, try:
n = 2
m = [[0 for _ in range(0, n)] for _ in range (0, n)]
m[0][0] = 1
print(m)
output is:
[[1, 0], [0, 0]]

Strange error when altering 2 dimensional lists in Python [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 3 years ago.
I've tried to make some code for a game in python 3.6.3 and when I try to change a value in a 2d list/array (in a list inside a list), it changes the values of that index in all the lists. Does anybody know why that's the case?
I've abstracted the problem to the exact part of the code that's going wrong. I've tried using different numbers and formats but the problem remains. Debugging tools don't help either.
#Strange error
list_1 = [0,0]
list_2 = [list_1, list_1, list_1]
list_2[0][1] = 1
print(list_2)
#Working normally
list_3 = [[0,0],[0,0],[0,0]]
list_3[0][1] = 1
print(list_3)
The actual result should be that both lists have the same output of [0, 1],[0, 0], [0, 0]. However the first list returns [0, 1],[0, 1],[0, 1] whereas the second list works normally with [0, 1],[0, 0], [0, 0] returned, even though both lists should return the exact same output.
you're just creating references to list1 3 times in list2
you should do list2 = [list(list1), list(list1), list(list1)], which creates copies of list1 instead of just references to it.

autofilling python list of lists [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 5 years ago.
When I create and fill a list of lists some odd behaviour pops up:
list1 = [[0,0,0],[0,0,0],[0,0,0]]
list2 = [[0]*3]*3
print('lists still look equal here:')
print(list1)
print(list2)
list1[1].pop(1)
list2[1].pop(1)
print('but not anymore:')
print(list1)
print(list2)
gives me this output:
lists look completely equal here:
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
but not anymore:
[[0, 0, 0], [0, 0], [0, 0, 0]]
[[0, 0], [0, 0], [0, 0]]
So the second list 'pops' from every little list instead of just the one I'm trying to. I wonder what causes this behaviour and if there is a more elegant way to fill indexable lists if I need a large amount of long lists instead of just these tiny ones?
When using the operator * it means the items are pointing to the same memory location.
Therefore when poping from the first list only the first item is removed.
And when poping from the second list, as each of the elements in the list pointing to the same memory location, all elements get affected.
Take a look at this:
list1 = [[0,0,0],[0,0,0],[0,0,0]]
list2 = [[0]*3]*3
for elem in list1:
print (id(elem))
print ('--------')
for elem in list2:
print (id(elem))
Output:
32969912
32937024
32970192
--------
32970752
32970752
32970752
As you can see, each element in the second list has the same id.
This is quite a common mistake. In the second definition:
list2 = [[0] * 3]*3
the three sub-lists share the same reference in memory, so if you pop from one, you pop from "all" of them, because all three of them point to the same object.
To avoid this, use:
list2 = [[0] * 3 for _ in range(3)]
which will generate different three lists.

Appending the same list to another one [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 6 years ago.
I have to append the same list to another one more than one time, and then modify only one of them.
I tried
list_a = []
list_b = [0,0,0]
for x in range(3):
list_a.append(list_b)
but the problem is that if I try
list_a[0][0] = 1
it modifies list_a[1][0] and list_a[2][0] also.
How can I avoid that?
Better way to create a list like this if all you want is to create empty list with all 0s is:
my_list = [[0]*3 for _ in range(3)]
Let's verify the result whether it has the same issue or not:
>>> my_list
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> my_list[0][0] = 1
>>> my_list
[[1, 0, 0], [0, 0, 0], [0, 0, 0]]
# ^ ^ ^
# Yipee! value changed only once
For knowing the reason why your code is not working, check: Python list of lists, changes reflected across sublists unexpectedly
Use the following:
list_a = []
list_b = [0,0,0]
for x in range(3):
list_a.append(list_b[:])
You are appending list_b three times, so what you are modifying is the actual list_b object. What you want to do is to make a shallow copy, this be done like this
list_a.append(list(list_b))
or like this
list_a.append(list_b[:])

Python list problem [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 5 years ago.
python:
m=[[0]*3]*2
for i in range(3):
m[0][i]=1
print m
I expect that this code should print
[[1, 1, 1], [0, 0, 0]]
but it prints
[[1, 1, 1], [1, 1, 1]]
This is by design. When you use multiplication on elements of a list, you are reproducing the references.
See the section "List creation shortcuts" on the Python Programming/Lists wikibook which goes into detail on the issues with list references to mutable objects.
Their recommended workaround is a list comprehension:
>>> s = [[0]*3 for i in range(2)]
>>> s
[[0, 0, 0], [0, 0, 0]]
>>> s[0][1] = 1
>>> s
[[0, 1, 0], [0, 0, 0]]
This is a bit devilish, but quite obvious when you understand what you're doing. when you're doing the [[0]*3]*2 bit, you're first creating a list with 3 zeros, then you copy that to make two elements. But when you do that copy, you do not create new lists with the same contents, but rather reference the same list several times. So when you change one, they all change.
An example to highlight it:
In [49]: s = [[]]*2 # Create two empty lists
In [50]: s # See:
Out[50]: [[], []]
In [51]: s[0].append(2) # Alter the first element (or so we think)
In [52]: s # OH MY, they both changed! (because they're the same list!)
Out[52]: [[2], [2]]

Categories