Wrong understanding of lists in Python? [duplicate] - python

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].

Related

How to initialize 2D list to be able to append sublists? [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 1 year ago.
My code is as follows:
l = [[]] * 10
for i in range(10):
l[i] += [0]
I need a 10 x 1 matrix of zeros.
It doesn't work as expected because the list comprises references to the same variable. As a result, I am getting a 10 x 10 matrix.
How to prevent it?
Try this:
l = [[] for _ in range(10)]
This will create 10 independent sublists. You can then modify any of them without affecting the others. (The use of _ for the loop variable is a common Python convention for an unused loop variable.)
Here's an example of how modifying one sublist leaves the others unaffected:
>>> l[2].append(5)
>>> l
[[], [], [5], [], [], [], [], [], [], []]
>>>
There multiples ways to obtain what you are looking for :
There some possibilites
Using list comprehension
L = [[0] for k in range (10)]
Using numpy np.zeros function
L = np.zeros((10,1)).tolist() # if you want a list and not an array

How can I append items to a list without changing the original list [duplicate]

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 1 year ago.
I have a list of lists that contain a list at the end. If this list has more than one element, I want to duplicate the entry and for each with the individual value without being in the list.
E.g.
[[1, [1,2]] -> [[1, 1][1, 2]]
There's probably a much more efficient solution than the one I've tried, but I'd like to understand why you're giving me the mistakes you're giving.
First, even though it indicates that it is not the same list, it is changing the value in both lists. Second, when I create the second element, it changes the previous one as well. Any explanation is welcome. Thanks
Variables in Python are just references. I recommend making a copy by using a slice. l_copy = l_orig[:]
When I first saw the question (pre-edit), I didn't see any code, so I did not have the context. It looks like you're copying the reference to that row. (Meaning it actually points to the sub-lists in the original.)
new_list.append(row[:])
Weird right? Look at the following example
lst1 = [1,2,3]
#bad copy example
_
lst2 = lst1
-
lst2.append(4)
print(lst1,lst2)
You would expect that only lst2 should have 4, but no. lst1 and lst2 both have 4.
[1, 2, 3, 4] [1, 2, 3, 4]
So to avoid a problem like this, we can use list2 = list1.copy()
lst1 = [1,2,3]
lst2 = lst1.copy()
lst2.append(4)
print(lst1,lst2)
output
[1, 2, 3] [1, 2, 3, 4]

python: create a new 1D list with values from 2 different lists: [duplicate]

This question already has answers here:
How do I concatenate two lists in Python?
(31 answers)
Closed 4 years ago.
Below is a simple example. What I want is to create a new list that contain the values [0,1,2,3,4] by merging list1 and list 2 together. But the code below doesn't work and I am not really sure how I should solve it.
list1 = [3]
list2 = [i for i in range(3)]
newlist = list1.append(list2)
list.append(b) doesn't return a new list containing the elements of list and b, but it will extend list by one element (the element b) and save the result in list itself.
To concatenate two lists, simply use the + operator. Your code would look like this:
list1 = [3]
list2 = [i for i in range(3)]
newlist = list1 + list2
#MathiasRa, your code will not work as append()
method doesn't return any list.
Previous answers are appreciated. So can directly get your merged list [0, 1, 2, 3] using the below line.
list1 = [3]
list2 = [i for i in range(3)]
newlist = sorted(list1 + list2)
print (newlist) # [0, 1, 2, 3]
ยป If you don't want updated list as return value
Use extend() method in place of append() as follows:
Note: In this case, you won't get anything returned like append(). The statement will update the calling list (list1) by appending all items of passing list (list2).
list1 = [3]
list2 = [i for i in range(3)]
list1.extend(list2)
print(list1) # [3, 0, 1, 2]
print(sorted(list1)) # [0, 1, 2, 3]

Appending to 2D lists in Python [duplicate]

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!

Python list elements removal logical error? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Removing from a list while iterating over it
I have this code:
s = [2,3,4,5]
for i in s:
s.remove(i)
print(s)
When I run it, the result is:
[3,5]
What is the logical error here ?
You are iterating over the list while modifying it, which is causing your problem.
Make a temporary list (list(s)) that you iterate over and modify the original to your needs:
>>> s = [2,3,4,5]
>>>
>>> for i in list(s):
... s.remove(i)
...
>>> print(s)
[]
The logical error is in removing elements from a list while iterating through the same list.
Python hides some implementation details, of course. Internally, you remove the first item, leaving [3,4,5]. Then you remove the second item, leaving [3,5]. At this point you have removed two items from a list that is only two items long, so you are done.
It is because of the iterator. Consider this code segment:
s = [2,3,4,5]
for i in s:
print "i",i
j = s
print "j", j
s.remove(i)
print "removed"
print "j", j
print "s", s
print s
The output would be
i 2
j [2, 3, 4, 5]
removed
j [3, 4, 5]
s [3, 4, 5]
i 4
j [3, 4, 5]
removed
j [3, 5]
s [3, 5]
[3, 5]
Basically, when you execute the for loop, the the internal iterator goes to s[0], then s[1], etc. When the next round of the loop executes, s[1] is already 4 instead of 3 because s itself has been modified.

Categories

Resources