Reputation: 2141
Assuming I have the following list:
array1 = ['A', 'C', 'Desk']
and another array that contains:
array2 = [{'id': 'A', 'name': 'Greg'},
{'id': 'Desk', 'name': 'Will'},
{'id': 'E', 'name': 'Craig'},
{'id': 'G', 'name': 'Johnson'}]
What is a good way to remove items from the list? The following does not appear to work
for item in array2:
if item['id'] in array1:
array2.remove(item)
Upvotes: 2
Views: 201
Reputation: 251116
for item in array2:
if item['id'] in array1:
array2.remove(item)
A for
loop keeps track of the index during the iterations.
Iteration 1 : Index 0
item
is assigned {'id': 'A', 'name': 'Greg'}
as it is at index 0.
As 'A'
as found in array so you removed this entry from the list.
Due to removal of that item all items to it's right actually shift one place to the left.
So, now {'id': 'Desk', 'name': 'Will'}
is at index 0.
Iteration 2 : Index value changed to 1
This time item
= {'id': 'E', 'name': 'Craig'}
as this is at index 1.
So, as you can see {'id': 'Desk', 'name': 'Will'}
was skipped (was never assigned to item
) and will not be removed as you expected.
A quick solution is to use a shallow copy of the list for iteration:
for item in array2[:]: #notice the [:]
Upvotes: 2
Reputation: 142216
Similar to Paulo's answer, but converting to a set
first within the filter:
array2[:] = filter(lambda L, S=set(array1): L['id'] not in S, array2)
Upvotes: 0
Reputation: 77359
You can use filter:
array2 = filter(lambda x: x['id'] not in array1, array2)
Upvotes: 4
Reputation: 132098
You could also use a list comprehension for this:
>>> array2 = [{'id': 'A', 'name': 'Greg'},
... {'id': 'Desk', 'name': 'Will'},
... {'id': 'E', 'name': 'Craig'},
... {'id': 'G', 'name': 'Johnson'}]
>>> array1 = ['A', 'C', 'Desk']
>>> filtered = [item for item in array2 if item['id'] not in array1]
>>> filtered
[{'id': 'E', 'name': 'Craig'}, {'id': 'G', 'name': 'Johnson'}]
Upvotes: 7
Reputation: 129537
You're modifying a list while iterating over it. Instead iterate over a copy of the list
for item in array2[:]: # [:] creates a copy
...
Upvotes: 3