W zasadzie potrzeba sprawdzenia każdego elementu listy i jeśli niektóre kryteria pasują, chcę go usunąć z listy.

Więc na przykład to powiedzmy

list=['a','b','c','d','e']

Zasadniczo chcę napisać (zasadniczo, a nie rzeczywisty kod, próbuję wdrożyć)

Jeśli element listy jest "B" lub "C" Usuń go z listy i przejdź dalej.

Ale

for s in list:
    if s=='b' or s=='c':
        list.remove(s)

Nie powiedzie się, ponieważ gdy "B" jest usuwana pętla przyjmuje "D", a nie "C" jako następnego elementu. Czy jest jakiś sposób, aby zrobić to szybciej niż przechowywanie elementów na osobnej liście i usuwając je później?

Dzięki.

10
tst 17 grudzień 2011, 15:58

4 odpowiedzi

Najlepsza odpowiedź

Łatwy sposób jest użycie kopii listy - można to zrobić za pomocą plasterka, który rozciąga się "od początku" do "końca" listy, takich jak:

for s in list[:]:
    if s=='b' or s=='c':
        list.remove(s)

Rozważałeś to, a to jest wystarczająco proste, aby być w swoim kodzie, chyba że ta lista jest naprawdę duża, aw krytycznej części kodu (jak, w głównej pętli gry akcji). W takim przypadku czasami używam następującego idiomu:

to_remove = []
for index, s in enumerate(list):
    if s == "b" or s == "c":
         to_remove.append(index)

for index in reversed(to_remove):
    del list[index]

Oczywiście możesz uciekać się do chwili zamiast pętli:

index = 0
while index < len(list):
   if s == "b" or s == "c":
       del list[index]
       continue
   index += 1
12
jsbueno 5 styczeń 2018, 12:45

Lepiej nie odwrócić rzeczy, które są już dostępne. Użyj Filtr Funkcje i Lambda w tych przypadkach. Jest bardziej pytający i wygląda do czyszczenia.

filter(lambda x:x not in ['b','c'],['a','b','c','d','e'])

Alternatywnie możesz użyć rozumienia listy

[x for x in ['a','b','c','d','e'] if x not in ['b','c']]
9
Abhijit 11 sierpień 2014, 09:10

Dokładnie jest to, do czego jest przeznaczony irtools.ifilter.

from itertools import ifilter

ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e'])

Dam ci powrót generatora swojej liście. Jeśli potrzebujesz listy, możesz utworzyć go za pomocą jednej ze standardowych technik do konwersji generatora do listy:

list(ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e']))

Lub

[x for x in ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e'])]
3
Charles Haynes 5 sierpień 2013, 01:04

Jeśli jesteś OK z tworzeniem kopii listy, możesz to zrobić w ten sposób (Rozumienie listy):

[s for s in list if s != 'b' and s != 'c']
1
gecco 17 grudzień 2011, 12:04