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?

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.


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,


16
# To support matches from the beginning, not any matches:

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

filter(lambda x: x.startswith(prefix), items)

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)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.