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.
Related
This question already has answers here:
Test if lists share any items in python
(9 answers)
Closed 1 year ago.
a = [1, 2, 3]
b = [4, 5, 1]
I need to check if one (or more) elements are common in both arrays.
Check the intersections of the sets and get the boolean:
>>> bool(set(a) & set(b))
True
>>>
Or not not:
>>> not not (set(a) & set(b))
True
>>>
Or just with any:
>>> any(i in b for i in a)
True
>>>
this is simple intersection concept which we used to learn in maths well here I have tried to demonstrate the function which take common from two list and return new list with common elements
def intersection(lst1, lst2):
lst3 = [value for value in lst1 if value in lst2]
return lst3
a = [1, 2, 3]
b = [4, 5, 1]
print(intersection(a,b))
This question already has answers here:
python: mutating the copy of a list changes the original?
(1 answer)
Why should I refer to "names" and "binding" in Python instead of "variables" and "assignment"?
(5 answers)
Closed 3 years ago.
#Case 1
myList=[1,2,3,4]
old=myList
myList=[5,6,7,8]
print(old)
#Case 2
myList=[1,2,3,4]
old=myList
myList[0]=10
print(old)
#Case 3
myList=[1,2,3,4]
old=myList.copy()
myList[0]=10
print(old)
[1, 2, 3, 4]
[10, 2, 3, 4]
[1, 2, 3, 4]
For me the case 3 is the safe case and Case 2 is clear. However, I am not able to clearly understand why in case 1 old is not changed.
In case 1, we are re-assigning a brand new list to the name myList. The original list that was assigned to myList is not affected by this operation; myList is now simply pointing to a different object
This becomes clear when we look at the ids of the objects:
>>> myList = [1,2,3,4]
>>> print(id(myList))
47168728
>>> old = myList
>>> print(id(old))
47168728
>>> myList = [5,6,7,8]
>>> print(id(myList))
47221816
>>> print(id(old))
47168728
Writing old = myList does not bind the two variables inextricably; it assigns the value of myList to old at that point in time. By reassigning myList to a new list afterwards, you are then making myList and old point to different values.
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:
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.
This question already has answers here:
Abnormal list behaviour
(2 answers)
Closed 9 years ago.
This is MWE of what I'm trying to do:
lis = []
# Initialize empty list
for i in range(2):
lis.append([[0]]*2)
# First print
print lis
# Second print
print lis[0][1][0]
# Modify item
lis[0][1][0] += 1
# Third print
print lis
The first print returns the list as [[[0], [0]], [[0], [0]]] which is correct, I have a first list which is composed of several lists, each one also composed of several lists (I need this nested lists for what I'm doing). The second print returns the item in indexes 0 and 1 as 0 which is also correct. But the third print shows me the new list as:
[[[1], [1]], [[0], [0]]]
instead of:
[[[0], [1]], [[0], [0]]]
which is what I actually aimed at. What am I doing wrong?
That is happening because both inner lists are actually copies of same object, so modifying one will affect the other one as well.
>>> l = [[0]]*2
>>> [id(x) for x in l]
[145328716, 145328716] #same IDs
>>> l[0].append(4)
>>> l
[[0, 4], [0, 4]]
Use a list comprehension to avoid that:
>>> l = [[0] for _ in xrange(2)]
>>> [id(x) for x in l] #Different IDs
[145327372, 145327500]
>>> l[0].append(4)
>>> l
[[0, 4], [0]]