How to Remove List Elements in a For Loop in Python

How to remove items from a list while iterating?

You can use a list comprehension to create a new list containing only the elements you don't want to remove:

somelist = [x for x in somelist if not determine(x)]

Or, by assigning to the slice somelist[:], you can mutate the existing list to contain only the items you want:

somelist[:] = [x for x in somelist if not determine(x)]

This approach could be useful if there are other references to somelist that need to reflect the changes.

Instead of a comprehension, you could also use itertools. In Python 2:

from itertools import ifilterfalse
somelist[:] = ifilterfalse(determine, somelist)

Or in Python 3:

from itertools import filterfalse
somelist[:] = filterfalse(determine, somelist)

How to remove list elements in a for loop in Python?

You are not permitted to remove elements from the list while iterating over it using a for loop.

The best way to rewrite the code depends on what it is you're trying to do.

For example, your code is equivalent to:

for item in a:
print(item)
a[:] = []

Alternatively, you could use a while loop:

while a:
print(a.pop())

I'm trying to remove items if they match a condition. Then I go to next item.

You could copy every element that doesn't match the condition into a second list:

result = []
for item in a:
if condition is False:
result.append(item)
a = result

Alternatively, you could use filter or a list comprehension and assign the result back to a:

a = filter(lambda item:... , a)

or

a = [item for item in a if ...]

where ... stands for the condition that you need to check.

Remove element from list of lists during loop

You need to make copy of original list and then iterate over new copy and remove the items from original list

for item in list(original_list):
...
original_list.remove(item)

In your case, code will look like below

total_read = 0

for i in range(21):
random.shuffle(info)
for index, value in enumerate(list(info)):
b, p, s = value
if len(s) <= i+1:
print("Overshot! Shouldn't see this sentence anymore: %s" % (s))
info.pop(index)
print s[:i+1], i, s

total_read += len(s[i + 1])

Python: How to remove elements from list while iterating through it without skipping future iterations

You are right. You need an additional list. But there is an easier solution.

def print_numTXTs(fileList):

counter = 0
for file in list(fileList):
if file.name[-4:] == ".txt":
counter +=1
if file.name == "a.txt":
fileList.remove(file)

The secret is "list(fileList)". You creating an additional list and iterates over this.

Just as powerful are list compressions. In your example it should work like this. I have not tried now...only quickly written here.

fileList = [ file for file in fileList if file.name != "a.txt" ]

Removing element from a list in a for loop

It's not a good idea to remove elements from a list while looping through it. You can always make a copy and update it:

import copy
my_list= copy.deepcopy(master_list)

However, a better approach would be to use list comprehensions:

master_list = [{"irrelevant_key": "irrevelant_value", 
"relevant_key":
[[{"first_value": "first_key"}, {"problem_key": 0}],
[{"second_value": "second_key"}, {"problem_key": 1}]],
}]
for lst in master_list:
lst['relevant_key'] = [x for x in lst['relevant_key'] if x[1]['problem_key'] != 0 ]

About removing an item from a list with a for loop

The second code works because a new list is created with list(a). You then iterate through the new list and remove items from the original list.

The second code is acceptable in the sense that you are not iterating through the same list you are modifying.

Python: Removing list element while iterating over list

You could always iterate over a copy of the list, leaving you free to modify the original:

for item in list(somelist):
...
somelist.remove(item)

Python 3: Removing list item with for loop, is this the right way?

Here are some examples

def example1(lst):
for item in lst:
if item < 4:
lst.remove(item)
return lst

def example2(lst):
for item in lst[:]:
if item < 4:
lst.remove(item)
return lst

def example3(lst):
i = 0
while i < len(lst):
if lst[i] < 4:
lst.pop(i)
else:
i += 1
return lst

def example4(lst):
return [item for item in lst if not item < 4]

def example5(lst):
for item in reversed(lst):
if item < 4:
lst.remove(item)
return lst

def example6(lst):
for i, item in reversed(list(enumerate(lst))):
if item < 4:
lst.pop(i)
return lst

def example7(lst):
size = len(lst) - 1
for i, item in enumerate(reversed(lst)):
if item < 4:
lst.pop(size - i)
return lst

def example8(lst):
return list(filter(lambda item: not item < 4, lst))

import itertools
def example9(lst):
return list(itertools.filterfalse(lambda item: item < 4, lst))

# Output
>>> lst = [1, 1, 2, 3, 2, 3, 4, 5, 6, 6]
>>> example1(lst[:])
[1, 3, 3, 4, 5, 6, 6]
>>> example2(lst[:])
[4, 5, 6, 6]
>>> example3(lst[:])
[4, 5, 6, 6]
>>> example4(lst[:])
[4, 5, 6, 6]
>>> example5(lst[:])
[4, 5, 6, 6]
>>> example6(lst[:])
[4, 5, 6, 6]
>>> example7(lst[:])
[4, 5, 6, 6]
>>> example8(lst[:])
[4, 5, 6, 6]
>>> example9(lst[:])
[4, 5, 6, 6]

Example 1
This example involves iterating through the list and removing values from it. The issue with this is that you are modifying the list as you go through it so your list changes during iteration and so some elements get skipped over.

Example 2
Here we are iterating over a shallow copy of the list instead of the list itself. The issue with this is if you have a large list it could be expensive to do so.

Example 3
The following is an example using pop instead of remove, the issue with remove is that it removes the first instance of the value it finds from the list. This will typically be of no issue unless you have objects which are equal. (See example 10)

Example 4
Instead of modifying the list here instead we create a new list using list comprehension allowing only specified values.

Example 5
This is an example of iterating through the list in reverse, the difference is that we use the built-in reversed function to apply a for-loop to in stead of a while loop with a counter.

Example 6
Similar example using pop instead.

Example 7
Better example using pop as we don't have to cast back to a list to use the reversed function.

Example 8
Example using the built-in filter method to remove the specified values.

Example 9
Similar example using the filerfalse method from itertools

class Example(object):
ID = 0
def __init__(self, x):
self._x = x
self._id = str(Example.ID)
Example.ID += 1

def __eq__(self, other):
return self._x == other._x

def __repr__(self):
return 'Example({})'.format(self._id)

def example10():
lst = [Example(5), Example(5)]
print(lst)
lst.remove(lst[1])
return lst

#Output
>>> example10()
[Example(0), Example(1)]
[Example(1)]

Example 10
Here we create two Example objects with the same values and by the equality method they are equal. The ID variable is there to help us differentiate between the two. Now we have specified that we want to remove the 2nd object from the list, however because both are equal the first item is actually removed instead.

Timings
These are pretty rough times and can vary slightly depending on your device. Although these identify which one is faster, this was tested with a list of 10,000 items so if you don't have anything close to that then any choice is fine really.

import timeit
import random

# Code from above is here

def test(func_name):
global test_lst
test_lst = lst[:]
return timeit.timeit("{}(test_lst)".format(func_name),
setup="from __main__ import {}, test_lst".format(func_name), number = 1)

if __name__ == '__main__':
NUM_TRIALS = 1000
lst = list(range(10000))
random.shuffle(lst) # Don't have to but makes it a bit interesting
test_list = lst[:]

for func in ('example2', 'example3', 'example4', 'example5',
'example6', 'example7', 'example8', 'example9'):
trials = []
for _ in range(NUM_TRIALS):
trials.append(test(func))
print(func, sum(trials) / len(trials) * 10000)

#Output
example2 8.487979147454494
example3 20.407155912623292
example4 5.4595031069025035
example5 7.945100572479213
example6 14.43537688078149
example7 9.088818018676008
example8 14.898256300967116
example9 13.865010859443247

I need to remove the elements of the list which are greater than 1 in python

You're modifying the list while you iterate over it. That means that the first time through the loop, I> 1, so I>1 is removed from the list. Then the for loop goes to the third item in the list, which is not 3, but 4! Then that's removed from the list, and then the for loop goes on to the third item in the list, which is now 4. And so on. Perhaps it's easier to visualize like so, with a ^ pointing to the value

Check the visualization of what's happening

[1, 2, 3, 4, 5, 6]
^
[1, 3, 4, 5, 6]
^
[1, 3, 5, 6]
^
[1, 3, 5]

For this example i>1 condition meets element 2 and removes it but 3 replaces the 2nd position of 2. Thus 3 is getting a skip to remove. This way 5 also skip and the final output will be like

[1, 3, 5]

To avoid this way of removing you can set a condition to skip the element you need to remove and append the elements into a new list that you don't need to delete like:

ls = [i for i in a if i <= 1]
print(ls)


Related Topics



Leave a reply



Submit