python deleting item from a list by specifying index [duplicate] - python

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 6 years ago.
I am tryin to delete an item from a list by specifying the index of the list I want to delete but I get an error.
My code:
tuu = [1,2,3,4,'nan', 8]
for i in range(len(tuu)):
if tuu[i] == 'nan':
del tuu[i]
but I get the error:
7 for i in range(len(tuu)):
----> 8 if tuu[i] == 'nan':
9 del tuu[i]
IndexError: list index out of range

When you use a for loop, Python will call __iter__ on the iterable you are looping over. __iter__ will return an iterator object which keeps track of where you are currently in your iterable.
If you modify the length of your iterable (the list) while looping over it, the iterator will get confused.
After deleting tuu[i] your list has one less element, but the iterator won't know and tries to access the previously last index -> that's where you get an IndexError.
The canonical way to filter a list in Python is to build a new list and reassign the name of the old list:
>>> tuu = [1, 2, 3, 4, 'nan', 8]
>>> tuu = [x for x in tuu if x != 'nan']
>>> tuu
[1, 2, 3, 4, 8]

Related

Dicts not being popped from list? [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 3 months ago.
The context doesn't matter too much, but I came across the problem that while trying to pop dict objects from a list, it wouldn't delete all of them. I'm doing this to filter for certain values in the dict objects, and I was left with things that should have been removed. Just to see what would happen, I tried deleting every item in the list called accepted_auctions (shown below), but it did not work.
for auction in accepted_auctions:
accepted_auctions.pop(accepted_auctions.index(auction))
print(len(accepted_auctions))
When I tested this code, print(len(accepted_auctions)) printed 44 into the console.
What am I doing wrong?
Modifying a list as you iterate over it will invalidate the iterator (because the indices of all the items are changing as you remove items), which in turn causes it to skip items. Don't do that.
The easiest way to create a filtered list is via a list comprehension that creates a new list, e.g.:
accepted_auctions = [a for a in accepted_auctions if something(a)]
Here's a simple example using a list comprehension to filter a list of ints to only the odd numbers:
>>> nums = list(range(10))
>>> nums
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> nums = [n for n in nums if n % 2]
>>> nums
[1, 3, 5, 7, 9]

Removing item in list in Python3 as a for loop - weird behavior [duplicate]

This question already has answers here:
Strange result when removing item from a list while iterating over it
(8 answers)
Closed 2 years ago.
lst = [1,2,3,4,5]
def rem_items(lst):
for i in lst:
print(lst)
time.sleep(1)
lst.remove(i)
rem_items(lst)
returns
[1, 2, 3, 4, 5]
[2, 3, 4, 5]
[2, 4, 5]
I can understand the first two lines, but why does it remove 3 instead of 2?
And why is it stopping after removing 3, not 2,4,5?
Thanks in advance
You are iterating over the list [1,2,3,4,5] and modifying its length.
Writing
for i in lst:
print(lst)
time.sleep(1)
lst.remove(i)
is the same as writing
lst_iter = iter(lst):
for i in lst_iter:
print(lst)
time.sleep(1)
lst.remove(i)
Internally iterator holds a pointer aka index aka position of current item in the list. The loop directive calls i=next(lst_iter) internally, until StopIteration exception is raised.
In your case calling next(lst_iter) for the 1st time returns first element of list [1,2,3,4,5], which is 1. Calling next(lst_iter) for the 2nd time returns second element of list [2,3,4,5], which is 3.
You are modifying the list while iterating over it. This is generally a Bad Thing to do and can lead to unpredictable results.
See here for more info:
Modifying list while iterating

Iterating over a list and removing elements after comparing them [duplicate]

This question already has answers here:
Strange result when removing item from a list while iterating over it
(8 answers)
How to remove items from a list while iterating?
(25 answers)
Closed 4 years ago.
I'm trying to iterate over a list of number and removing the values that are lower than a number that I use to compare.
My problem is that there's a number that is lower than the value that I use but it doesnt get removed.
I'm using the remove() function of the list but I don't know why it doesn't get removed
Here is my code:
def remove_lower_numbers(array_numbers, bigger_number):
for elem in array_numbers:
if elem <= bigger_number:
array_numbers.remove(elem)
print(array_numbers)
It works if I used a list comprehension like this:
array_numbers = [x for x in array_numbers if x >= bigger_number]
but I want to do it the way I firts mentioned for learning purposes
I call the function like this:
cards_array = [3, 2, 7]
remove_lower_numbers(cards_array, 8)
but the function prints:
[2]
and 2 is lower than 8 it should return None or a empty list.
Using filter, which keeps only the values that return True for the lambda function:
list(filter(lambda x: x > 3, [1, 2, 3, 4, 5, 2, 3]))
Output:
[4, 5]

Weird behaviour when iterating through list and deleting elements in python [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 4 years ago.
I'm trying to iterate over a Python list and delete each element once I've done some tasks with it, but it jumps one element after each iteration and I don't know why:
>>> simple_list = list(range(10))
>>> simple_list
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for i in simple_list:
... print(i)
... simple_list.remove(i)
...
0
2
4
6
8
>>> simple_list
[1, 3, 5, 7, 9]
Does anyone know why this is happening? Only the even elements are being removed, and looks like the loop doesn't go through the uneven ones.
Well, your list is shrinking while you are iterating over it. If you want to, just look at the first element while your iterate over it.
while len(simple_list) > 0:
print(simple_list[0])
del simple_list[0]
You can use list comprehension to get copy of the array and then iterate.
simple_list = list(range(10))
for i in simple_list[:]:
print(i)
simple_list.remove(i)
Or this:
for i in simple_list[:]:
simple_list.remove(i)
print(simple_list)
Output:
[]
Ok, found the answer here: Python: Removing list element while iterating over list
You should NEVER delete an element from a list while iterating over it in a for loop. You could use a while loop instead. Or, record the indices of all the elements you want to remove and then delete them after the iteration is complete

Ternary operator in enumeration loop [duplicate]

This question already has answers here:
list comprehension with multiple conditions (python)
(2 answers)
Closed 6 years ago.
In my code, I'm trying to loop through an enumeration object and selectively add some values from the enumeration to a new list using a list comprehension.
This works:
a = [1, 2, 3, 4, 5]
s = [i[1] for i in enumerate(a)]
Of course, that basically just copies list a over to s.
This doesn't work (a being the same list):
s = [i[1] if i[1] != 2 for i in enumerate(a)]
I would think that this would just copy every element of list a over to s besides the 2, but instead I get a syntax error. Anybody know what's going on here?
You misplaced the if part:
s = [i[1] for i in enumerate(a) if i[1] != 2]

Categories