roll_number = [47, 64, 69, 37, 76, 83, 95, 97]
sample_dict = {'Jhon':47, 'Emma':69, 'Kelly':76, 'Jason':97}
for a in roll_number:
if a not in sample_dict.values():
roll_number.remove(a)
print(roll_number)
My output is [47, 69, 76, 95, 97] instead of [47, 69, 76, 97]. Can someone please explain?
CodePudding user response:
The issue I see is that you're iterating over the array while removing items from it. That leads to unsafe removal.
You could use a set
to 'freeze' the array and remove its values safely:
roll_number = [47, 64, 69, 37, 76, 83, 95, 97]
sample_dict = {'Jhon':47, 'Emma':69, 'Kelly':76, 'Jason':97}
roll_set = set(roll_number)
for a in roll_number:
if a not in sample_dict.values():
roll_set.remove(a)
print(roll_set)
It'll print {97, 69, 76, 47}
. If you want a list you can use list(roll_set)
.
Althoug set is a standard python type, you could also use another temporary list and would have the same result.
CodePudding user response:
You are removing elements while iterating the list. (Bad Idea) Removing elements while iterating the list will affect the iterator.
As mentioned here, there are several approaches:
- use a list comprehension to create a new list containing only the elements you don't want to remove
- create a copy of the original list
- by assigning to the slice
somelist[:]
, you can mutate the existing list to contain only the items you want - use
itertools
- iterate backwards
CodePudding user response:
I believe it happen because you remove a value from an array while you loop on the exist array, just copy the existing array and remove the values of the copy
import copy
roll_number = [47, 64, 69, 37, 76, 83, 95, 97]
sample_dict = {'Jhon': 47, 'Emma': 69, 'Kelly': 76, 'Jason': 97}
roll_number_b = copy.deepcopy(roll_number)
for a in roll_number:
if a not in sample_dict.values():
roll_number_b.remove(a)
print(roll_number_b)
#output: [47, 69, 76, 97]
CodePudding user response:
I would use a list comprehension:
[x for x in roll_number if x in sample_dict.values()]
[47, 69, 76, 97]
You can see the example in this question:
How to remove items from a list while iterating?
CodePudding user response:
It is because the result
is being updated in the loop.
To understand the behavior of the code, consider this example:
>>> lst = [1, 2, 3]
>>> lst.pop(0)
1
>>> lst.pop(1)
3
You can obtain the expected output with this code (using the while
loop and only incrementing the loop counter when the element does not remove):
i = 0
while i < len(roll_number):
if roll_number[i] not in sample_dict.values():
roll_number.pop(i)
else:
i = 1
Output
The output with the above code and with the given input is:
[47, 69, 76, 97]