This question already has answers here:
Generating sublists using multiplication ( * ) unexpected behavior [duplicate]
(5 answers)
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 9 years ago.
the trick is:
IPython prompt:
In [1]: A = [ [] ] * 2
In [2]: A
Out[2]: [[], []]
In [3]: A[0].append(1)
In [4]: A
Out[4]: [[1], [1]]
Obvious, it's not my expected result, what's I want is [[1], []]. So why? I found no ref in the docs about python multiply sequence.
And is there any elegant(use no any explicit loop) ways to do that?
A = [ [] ] * 2 creates a list with two references to the same list:
>>> A = [ [] ] * 2
>>> id(A[0])
24956880
>>> id(A[1])
24956880
>>> id(A[0]) == id(A[1])
True
>>>
Instead, you need to use a list comprehension:
>>> A = [[] for _ in xrange(2)]
>>> A
[[], []]
>>> A[0].append(1)
>>> A
[[1], []]
>>>
Note that, if you are on Python 3.x, you will need to replace xrange with range.
[ [] ] is an array containing (a reference to) a list. When you multiply it by 2, you get a list containing two references to the same list. Try this:
A = [[] for i in range(5)]
It will generate a new empty list for every tick of range.
There can't really be a no-loop version of this, because you really need to construct multiple lists; there can be no shortcut.
Related
This question already has answers here:
Changing an element in one list changes multiple lists [duplicate]
(4 answers)
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 2 years ago.
I notice this interesting thing in python:
>>> B = [[]*5 for _ in range(5)]
>>> B
[[], [], [], [], []]
>>> B[0].append(1)
>>> B
[[1], [], [], [], []]
>>>
Then I do this:
>>> B = [[]]*5
>>> B
[[], [], [], [], []]
>>> B[0].append(1)
>>> B
[[1], [1], [1], [1], [1]]
>>>
It seems B = [[]]*5 and B = [[]*5 for _ in range(5)] generate the same empty list B but why they behave different when using append? Thank you for anyone who cares to explain!
Because in second one you don't create new empty list. you just add the same list 5 time. Because of that when you select the first one and append to it t will affect on all of them. Because all are the same.
try this for sure in second one:
print(B[0] is B[1])
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 5 years ago.
I am new to Python, so I apologize if this question is naive.
I consider a list elements = [3, 6, 7]. I would like to write a series of instructions which transform the list l = [[], [], []] into l = [[3], [6], [7]]. If I write the (naive) code below :
pos = 0
for i in range(3):
l[i].append(elements[i])
print(l)
then the output is not as I expected. Indeed, the list l becomes l=[[3, 6, 7], [3, 6, 7], [3, 6, 7]]. My reasoning was the following one : when i=0 only l[0] (the first element of l) should be modified. However, it is not the case. After the first run in the loop, the list l is : l = [[3], [3], [3]]. Where am I wrong ?
Of course, this could be easily solved using list comprehension:
l = [[elements[j]] for j in range(3)]
The problem is in the part of the code you haven't posted (that's why you should post complete examples when you ask questions here).
What has happened is that l contains three references to the same list. When you append an element to that list and then print l, you still see three copies of that list.
You need to create l in a way that truly makes three separate lists:
l = [ [], [], [] ] #good
l = [ [] for x in range(3) ] #good
l = [ [] ] * 3 #bad
Three copies of the same list
It appears that you've constructed your list 'l' not from three empty lists, but of three references to the same single empty list. This means that any changes done to it through l[0] are reflected also if you look at the same list through l[1].
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 9 years ago.
Could somebody please explain the following behaviour?
X=2*[[]]
print X
X[0].append(1)
print X
yields
[[], []]
[[1], [1]]
I would expect the last list to be [[1], []]. Indeed, the following
X=[[],[]]
print X
X[0].append(1)
print X
yields
[[], []]
[[1], []]
Why this difference?
The multiplication syntax you used creates a shallow copy of the contents. Each list element within will be a new reference to the same list.
The second example you give actually produces a list of two different lists.
y = 2*[x]
is roughly equivalent to doing
y = [x] + [x]
The x in both places refers to the same list.
>>> y = 2*[[]]
>>> y[0].append(1)
>>> y
[[1], [1]]
>>> x = []
>>> y = [x] + [x]
>>> y
[[], []]
>>> y[0].append(1)
>>> y
[[1], [1]]
To create a list that functions as your second example, try
>>> y=[[] for n in range(2)]
>>> y[0].append(1)
>>> y
[[1], []]
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Why does this code for initializing a list of lists apparently link the lists together? [duplicate]
(1 answer)
Closed 9 years ago.
I have this scenario:
>>> y=[[1]]
>>> y=y*2
>>> y
[[1], [1]]
>>> y[0].append(2)
>>> y
[[1, 2], [1, 2]]
What I'd like to do is add the 2 into the first list within the outer list i.e. this is the desired output:
[[1, 2], [1]]
Doing:
y=[[1]]
y=y*2
creates a list with two references to the same list object:
>>> y=[[1]]
>>> y=y*2
>>> id(y[0]) # The id of the first element...
28864920
>>> id(y[1]) # ...is the same as the id of the second.
28864920
>>>
This means that, when you modify one, the other will be affected as well.
To fix the problem, you can use a list comprehension instead:
>>> y = [[1] for _ in xrange(2)] # Use range here if you are on Python 3.x
>>> y
[[1], [1]]
>>> id(y[0]) # The id of the first element...
28864920
>>> id(y[1]) # ...is different from the id of the second.
28865520
>>> y[0].append(2)
>>> y
[[1, 2], [1]]
>>>
Replace: y=y*2 by y.append([1]) to have different references.
This question already has answers here:
2D list has weird behavor when trying to modify a single value [duplicate]
(3 answers)
Closed 3 years ago.
I've encountered what I think is a strange behavior in Python, and I'd like somebody to explain it if possible.
I've created an empty 2D list
listy = [[]]*3
print listy
[[], [], []]
The following works as I'd expect:
listy[1] = [1,2] yields [[], [1,2], []]
listy[1].append(3) yields [[], [1,2,3], []]
However, when I append to one of the empty lists, python appends to ALL of the sublists, as follows:
listy[2].append(1) yields [[1], [1,2,3], [1]].
Can anyone explain to me why this behavior occurs?
You haven't created three different empty lists. You've created one empty list, and then created a new list with three references to that same empty list. To fix the problem use this code instead:
listy = [[] for i in range(3)]
Running your example code now gives the result you probably expected:
>>> listy = [[] for i in range(3)]
>>> listy[1] = [1,2]
>>> listy
[[], [1, 2], []]
>>> listy[1].append(3)
>>> listy
[[], [1, 2, 3], []]
>>> listy[2].append(1)
>>> listy
[[], [1, 2, 3], [1]]
[[]]*3 is not the same as [[], [], []].
It's as if you'd said
a = []
listy = [a, a, a]
In other words, all three list references refer to the same list instance.
Came here to see how to append an item to a 2D array, but the title of the thread is a bit misleading because it is exploring an issue with the appending.
The easiest way I found to append to a 2D list is like this:
list=[[]]
list.append((var_1,var_2))
This will result in an entry with the 2 variables var_1, var_2. Hope this helps!