I'm trying to remove all instances of a value ("c") from a list.
letters = ["a", "b", "c", "c", "d"]
for i in letters:
if i == "c":
letters.remove(i)
print(letters)
The output is ["a", "b", "c", "d"] instead of the intended ["a", "b", "d"]
Why is it that only one "c" is removed, and not both/all?
CodePudding user response:
Filter is the right approach, when you have to filter the contents of a list.
list(filter(lambda x: x!='c', letters))
['a', 'b', 'd']
CodePudding user response:
You are updating a list and iterating it at the same time. When you remove the first c
your new list will be ["a", "b", "c", "d"]
but the index is stil in the 3rd position (where was the first c
) so it moves directly to 4th position.
If you change your list to ["a", "b", "c", "d", "c"]
you won't see the problem.
I suggest that you create a completely new list:
letters = ["a", "b", "c", "c", "d"]
new_letters = [i for i in letters if i != "c"]
print(new_letters)
CodePudding user response:
I recommend not deleting/adding elements inside a loop on the list's elements. Believe creating a new list and copying all the relevant elements to the new list will be better.
CodePudding user response:
Find duplictaes
and then filter
letters = ["a", "b", "c", "c", "d"]
duplicates = []
for i in letters:
count = letters.count(i)
if count > 1 and i not in duplicates:
duplicates.append(i)
#Filter
print([x for x in letters if x not in duplicates])
output#
['a', 'b', 'd']
CodePudding user response:
Here is an (admittedly ugly but working) implementation with a for loop:
letters = ["a", "b", "c", "c", "d"]
for i in range(len(letters)-1, -1, -1):
if letters[i] == "c":
del(letters[i])
print(letters)
Explanation: counting backwards solves the index problem mentioned by Aymen
CodePudding user response:
You can remove the duplicates using collections.Counter
,
In [1]: from collections import Counter
In [2]: [k for k, v in Counter(letters).items() if v == 1]
Out[2]: ['a', 'b', 'd']