Filtrowanie listy ciągów na podstawie zawartości

104

Biorąc pod uwagę listę ['a','ab','abc','bac'], chcę obliczyć listę zawierającą ciągi znaków, które zawierają 'ab'. To znaczy wynik jest ['ab','abc']. Jak można to zrobić w Pythonie?

Chris.Jie
źródło

Odpowiedzi:

173

To proste filtrowanie można osiągnąć na wiele sposobów w Pythonie. Najlepszym podejściem jest użycie „wyrażeń listowych” w następujący sposób:

>>> lst = ['a', 'ab', 'abc', 'bac']
>>> [k for k in lst if 'ab' in k]
['ab', 'abc']

Innym sposobem jest użycie filterfunkcji. W Pythonie 2:

>>> filter(lambda k: 'ab' in k, lst)
['ab', 'abc']

W Pythonie 3 zwraca iterator zamiast listy, ale możesz go rzucić:

>>> list(filter(lambda k: 'ab' in k, lst))
['ab', 'abc']

Chociaż lepiej jest używać zrozumienia.

Eli Bendersky
źródło
31
@ S.Lott: dlaczego? Co jest złego w uczeniu się przydatnych zaawansowanych tematów programowania w odpowiednim kontekście?
Eli Bendersky
12
@ S.Lott: Myślę, że lambdy ułatwiają rozpatrywanie funkcji jako obiektów pierwszej klasy, co jest ważne w przypadku niektórych paradygmatów programowania. Nie powiedziałbym, że są dla mnie bardzo ważne , ale wierzę, że nawet początkujący mogą skorzystać na myśleniu o programowaniu w ten sposób i zdecydowanie nie nazwałbym tego zadawaniem .
Eli Bendersky
6
@ S.Lott: ale czy nie jest lambdaidealnym towarzyszem filterw tym przypadku? Myślę, że napisanie oddzielnej funkcji tylko do sprawdzenia, czy abjest na podanej liście, jest przesadą. Tak samo jest z pisaniem bardziej ogólnej funkcji, która w zasadzie otacza inoperatora. Jak byś używał filterw jaśniejszy sposób bez lambdatutaj?
Eli Bendersky
5
To nie tylko n00bs, którzy znajdują tę odpowiedź
Bryan
10
Jestem n00b i teraz zapoznałem się z lambdą. czuję się wspaniale wiedzieć to teraz dowiem się o tym więcej.
a_secenthusiast,
17
[x for x in L if 'ab' in x]
Ignacio Vazquez-Abrams
źródło
16
# To support matches from the beginning, not any matches:

items = ['a', 'ab', 'abc', 'bac']
prefix = 'ab'

filter(lambda x: x.startswith(prefix), items)
Itay Maman
źródło
unikaj listy jako nazwy zmiennej, ponieważ jest to typ obiektu Pythona.
Rutger Hofste
6

Wypróbowałem to szybko w interaktywnej powłoce:

>>> l = ['a', 'ab', 'abc', 'bac']
>>> [x for x in l if 'ab' in x]
['ab', 'abc']
>>>

Dlaczego to działa? Ponieważ inoperator jest zdefiniowany dla łańcuchów znaków, aby oznaczać: „jest podłańcuchem”.

Możesz również rozważyć napisanie pętli w przeciwieństwie do używania składni list składni używanej powyżej:

l = ['a', 'ab', 'abc', 'bac']
result = []
for s in l:
   if 'ab' in s:
       result.append(s)
Daren Thomas
źródło
-2
mylist = ['a', 'ab', 'abc']
assert 'ab' in mylist
Yann Ramin
źródło