Function append in python 3 [duplicate] - python

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 4 years ago.
I wonder why append add a number to every list that I have in my list. Not only to that one ([0]) that I have choosen. What's the difference between writing [0] or any other number next to append?
j = [[]] * 5
j[0].append(5) # add 5 to every list on list
j[1].append(4) # what's the diffrence? [1] or [0]; it adds number to every element anyway
print (j)
j.append(0) # add 0 to the main list
print (j)

This happens because your initial list j contains 5 references to the same object (so 5 copies to the same list). That's why everything you append goes to every list.
Instead, if you actually create 5 different sublists:
j = [[] for _ in range(5)]
Then it will work as you expect:
[[5], [4], [], [], [], 0]

There is no difference.
j = [[]] * 5
Repeats the same empty list instance five times, once at each index.
IOW, the initial empty list is referenced 5 times.
You could verify this:
id(j[0]) == id(j[1])
To instantiate a different empty list at each index requires a comprehension:
[[] for _ in range(5)]

Related

Appending in nested arrays causes all arrays to be appended [duplicate]

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'

Add element in a list in a list [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 2 years ago.
I have a list of list and I would like to add an element inside only one of the list but it is added everywhere. You can find my code bellow
repartition_labels = [[]]*3
repartition_labels[2].append(2)
The result I have is
[[2], [2], [2]]
and I would like to have the result
[[], [], [2]]
I already tried to function insert and extend but it didn't solve the problem
With repartition_labels = [[]]*3, you are generating a list which contains 3 references to the same object.
When you change that object, all references will show the (same) updated object.
You have to do this:
repartition_labels = [[] for _ in range(0, 3)]
repartition_labels[2].append(2)
Output:
[[], [], [2]]
The reason your code is not working as expected, is because by [[]] * 3 you're creating three references to the same list.

Why doesn't the first list do the same as the second? [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 2 years ago.
result_list = [[]]*3
print(result_list) #output [[],[],[]]
result_list[0].append(0)
result_list[1].append(33)
result_list[2].append(2)
print(result_list) #output [[0,33,2],[0,33,2],[0,33,2]]
# ???????????
list = [[],[],[]]
print (list) #output [[],[],[]]
list[0].append(0)
list[1].append(33)
list[2].append(2)
print (list) #output [[0],[33],[2]]
#normal
I want to make a list, where I can say, how many [] there should be (like in the first example with *3), but I want that list to behave like the second example, so that I can append to each [] individually.
[[]]*3
Actually is making one inner list [] which is referenced 3 times, so you are appending to the same list every time ... the alternative:
result_list = [[] for i in range(3)]
Why doesn't the first list do the same as the second?
Because the * operator on list simply adds new references to the original, so [[]]*3 is equivalent to (but faster than):
container = []
content = []
for _ in range(3):
container.append(content)
therefore you get the same inner list 3 times, rather than three different lists.
I want to make a list, where I can say, how many [] there should be (like in the first example with *3), but I want that list to behave like the second example, so that I can append to each [] individually.
l = [[] for _ in range(n)]
PS: don't call things list, list is a builtin, don't override builtins.

How to create a second list in python, relative with first list [duplicate]

This question already has answers here:
Sum one number to every element in a list (or array) in Python
(5 answers)
Closed 2 years ago.
I have a question, how can we create a second list in python, which every content of this list is about 10 larger than first list. I can't solve it by loop(for).
For example:
l1[2] = 2
l2[2] = 12
or
l1 = [0,1,2,3]
l2 = [10,11,12,13]
Thank You
Just try (This is a list comprehension, where it iterates over the first list and adds 10 to each item):
l2 = [x+10 for x in l1]
print(l2)
This is the short version of:
l2 = []
for i in l1:
l2.append(i+10)

Create sub-lists in lists in Python [duplicate]

This question already has answers here:
Nested List Indices [duplicate]
(2 answers)
Having trouble making a list of lists of a designated size [duplicate]
(1 answer)
Closed 9 years ago.
I'm trying to figure out how to add a sub-list to a list in Python. For example, the code I was using before was just:
pop = [[],[],[],[],[],[],[],[],[],[]]
But I want to add user input to the length of the pop array, ie. how many arrays are added. I've looked at some other stackoverflow questions, and some of them suggested something like:
popLen = 5
pop = [None]*popLen
But when I try that it creates a list with 5 None elements instead of an empty array. I've tried:
pop = [[]]*popLen
What's the proper way to sub-lists?
pop = [[]]*popLen should work, but it is likely not what you want since it creates a list filled with the same nested list popLen times, meaning that a change to one of the list elements would appear in the others:
>>> a = [[]] * 3
>>> a[0].append(42)
>>> a
[[42], [42], [42]]
A better alternative would be
pop = [[] for _ in range(popLen)] # use xrange() in Python 2.x
which eliminates this issue:
>>> a = [[] for _ in range(3)]
>>> a[0].append(42)
>>> a
[[42], [], []]
You can do:
pop = [[] for x in range(popLen)]
Don't try to multiply [[]] - that will actually work, but will do something different than you expect (it will give you copies of the same list, so you cannot change them independently).

Categories