This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 1 year ago.
I intend to initialize a list of list with length of n.
x = [[]] * n
However, this somehow links the lists together.
>>> x = [[]] * 3
>>> x[1].append(0)
>>> x
[[0], [0], [0]]
I expect to have something like:
[[], [0], []]
Any ideas?
The problem is that they're all the same exact list in memory. When you use the [x]*n syntax, what you get is a list of n many x objects, but they're all references to the same object. They're not distinct instances, rather, just n references to the same instance.
To make a list of 3 different lists, do this:
x = [[] for i in range(3)]
This gives you 3 separate instances of [], which is what you want
[[]]*n is similar to
l = []
x = []
for i in range(n):
x.append(l)
While [[] for i in range(3)] is similar to:
x = []
for i in range(n):
x.append([]) # appending a new list!
In [20]: x = [[]] * 4
In [21]: [id(i) for i in x]
Out[21]: [164363948, 164363948, 164363948, 164363948] # same id()'s for each list,i.e same object
In [22]: x=[[] for i in range(4)]
In [23]: [id(i) for i in x]
Out[23]: [164382060, 164364140, 164363628, 164381292] #different id(), i.e unique objects this time
Related
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 8 months ago.
Possible dupe: Append value to one list in dictionary appends value to all lists in dictionary
I've encountered a problem in using nested arrays, where all elements are updated, when I only want to append to a specific index.
x = [[]] * 6
x[0].append(1)
# expected: [[1], [], [], [], [], []]
# result: [[1], [1], [1], [1], [1], [1]]
What I'm guessing is that x[0] returns [], which turns the statement to [].append(1) and updates all empty lists. This is supported by the fact that non-empty sets will not be changed.
x = [[]] * 6
x[1] = [0]
x[0].append(1)
# [[1], [0], [1], [1], [1], [1]]
I currently do this workaround to assign the value:
x = [[]] * 6
y = x[0].copy()
y.append(1)
x[0] = y
I want to understand 1) why python would evaulate the x[0] bit and make [].append() apply to multiple elements in the list, if my theory is correct and 2) if there is a better way to add values in a nested list.
The statement x = [[]] * 6 creates a list with 6 references to the same list. Thus, when you append an element to any of them, the others are also updated.
When you say x[1] = [0], you've replaced x[1] entry with a new list. Thus, when updating another entry this new list will not be updated.
If you want to create a list that consists of 6 independent lists, do
[[] for _ in range(6)]
In python, list, dict, set, tuples are collection data types. It means, if you declare a variable based on collection, you have the address of the collection.
If you duplicate a collection, you have the same address for every duplication. It is the case when you do it: x = [[]] * 6
If you modify one element, it affects all of his copies.
In line x = [[]] * 6, you creating a list x with 6 reference to the same inner list []. To make it simple, x = [[]] * 6 is equivalent to:
inner_list = []
x = []
for _ in range(6):
x.append(inner_list) # here same 'inner_list' is appended 6 times
So, what you want to do here is:
x = []
for _ in range(6):
inner_list = []
x.append(inner_list) # here you are creating 6 different 'inner_list' and appending it to 'x'
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 1 year ago.
I intend to initialize a list of list with length of n.
x = [[]] * n
However, this somehow links the lists together.
>>> x = [[]] * 3
>>> x[1].append(0)
>>> x
[[0], [0], [0]]
I expect to have something like:
[[], [0], []]
Any ideas?
The problem is that they're all the same exact list in memory. When you use the [x]*n syntax, what you get is a list of n many x objects, but they're all references to the same object. They're not distinct instances, rather, just n references to the same instance.
To make a list of 3 different lists, do this:
x = [[] for i in range(3)]
This gives you 3 separate instances of [], which is what you want
[[]]*n is similar to
l = []
x = []
for i in range(n):
x.append(l)
While [[] for i in range(3)] is similar to:
x = []
for i in range(n):
x.append([]) # appending a new list!
In [20]: x = [[]] * 4
In [21]: [id(i) for i in x]
Out[21]: [164363948, 164363948, 164363948, 164363948] # same id()'s for each list,i.e same object
In [22]: x=[[] for i in range(4)]
In [23]: [id(i) for i in x]
Out[23]: [164382060, 164364140, 164363628, 164381292] #different id(), i.e unique objects this time
This question already has an answer here:
Why does this code for initializing a list of lists apparently link the lists together? [duplicate]
(1 answer)
Closed 4 years ago.
>>> f = [[]] * 3
[[], [], []]
>>> f[0].append(1)
[[1], [1], [1]]
I think [[]] * x creates a list of x lists, but each inner list is the same object so changing one inner list changes all the others.
How can I quickly initialise a list of lists, but have each inner list be unique?
I want
>>> f = something
[[], [], []]
>>> f[0].append(1)
[[1], [], []]
Use
f = [[] for _ in range(3)]
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 1 year ago.
I intend to initialize a list of list with length of n.
x = [[]] * n
However, this somehow links the lists together.
>>> x = [[]] * 3
>>> x[1].append(0)
>>> x
[[0], [0], [0]]
I expect to have something like:
[[], [0], []]
Any ideas?
The problem is that they're all the same exact list in memory. When you use the [x]*n syntax, what you get is a list of n many x objects, but they're all references to the same object. They're not distinct instances, rather, just n references to the same instance.
To make a list of 3 different lists, do this:
x = [[] for i in range(3)]
This gives you 3 separate instances of [], which is what you want
[[]]*n is similar to
l = []
x = []
for i in range(n):
x.append(l)
While [[] for i in range(3)] is similar to:
x = []
for i in range(n):
x.append([]) # appending a new list!
In [20]: x = [[]] * 4
In [21]: [id(i) for i in x]
Out[21]: [164363948, 164363948, 164363948, 164363948] # same id()'s for each list,i.e same object
In [22]: x=[[] for i in range(4)]
In [23]: [id(i) for i in x]
Out[23]: [164382060, 164364140, 164363628, 164381292] #different id(), i.e unique objects this time
This question already has answers here:
Python: fastest way to create a list of n lists
(5 answers)
Closed 8 years ago.
In python []*2, gives []
What is the simplest way to get [[],[]] instead?
You probably want:
[[] for _ in range(n)]
Unlike [[]] * n, this will give you unique inner lists (appending to one doesn't append to them all). e.g.:
>>> x = [[] for _ in range(n)]
>>> x[0].append(1)
>>> x
[[1], [], []]
compared to:
>>> x = [[]] * 3
>>> x[0].append(1)
>>> x
[[1], [1], [1]]
Note that this latter idiom ([[]] * n) is a very common mistake that crops up around here in different contexts pretty frequently.
Use comprehension:
[[] for _ in range(2)]
That's because (e.g.) [1]*3 gives [1,1,1], i.e., a sequence containing the contents of the list.
Hence you want to duplicate the value []:
a = [[]]*2
giving
[[], []]
Because of the way the * operator works, this gives copies of the same list. Hence, if you try to modify either of those inner empty lists, it effects both of them. (Since they're empty, just about the only thing you can do is append to them; i.e., a[0].append(1) gives [[1],[1]].) This is possibly, but unlikely, what you want.