Wyrażenia regularne: szukaj na liście

91

Chcę filtrować ciągi znaków na liście na podstawie wyrażenia regularnego.

Czy jest coś lepszego niż [x for x in list if r.match(x)]?

leoluk
źródło

Odpowiedzi:

117

Możesz utworzyć iterator w Pythonie 3.x lub listę w Pythonie 2.x przy użyciu:

filter(r.match, list)

Aby przekonwertować iterator Pythona 3.x na listę, po prostu rzuć go; list(filter(..)).

sepp2k
źródło
2
Właściwie listy składane są zwykle preferowane niż konstrukcje funkcjonalne, takie jak filtr, redukcja, lambda itp.
Ivo van der Wijk
39
@Ivo: Zwykle są preferowane, ponieważ są zwykle bardziej przejrzyste i często bardziej zwięzłe. Jednak w tym przypadku filterwersja jest doskonale czytelna i ma znacznie mniejszy hałas.
Sepp2k
9
co r.matchtu jest
rbatt
2
@rbatt r.matchto metoda, która po zastosowaniu do danego ciągu sprawdza, czy wyrażenie regularne rpasuje do tego ciągu (i zwraca odpowiedni obiekt dopasowania, jeśli tak, ale to nie ma znaczenia w tym przypadku, ponieważ zależy nam tylko na tym, czy wynik jest prawdziwy)
wrzesień
175

Pełny przykład (Python 3):
W przypadku języka Python 2.x zajrzyj do poniższej uwagi

import re

mylist = ["dog", "cat", "wildcat", "thundercat", "cow", "hooo"]
r = re.compile(".*cat")
newlist = list(filter(r.match, mylist)) # Read Note
print(newlist)

Wydruki:

['cat', 'wildcat', 'thundercat']

Uwaga:

W przypadku programistów Python 2.x filterzwraca już listę. W Pythonie 3.xfilter został zmieniony, aby zwracał iterator, więc musi zostać przekonwertowany list(aby ładnie go wydrukować).

Przykład kodu w Pythonie 3 Przykład kodu w
Pythonie 2.x.

Rtęć
źródło
4
Cześć, Kiedy uruchomię powyższy kod, dostaję <filter object at 0x1057acda0>Co robię źle?
1
Zgodnie z dokumentacją pythona (python 2.7.12): docs.python.org/2/library/functions.html#filter filter zwraca listę, a nie obiekt. Możesz również sprawdzić ten kod: repl.it/X3G/5786 (po prostu uruchom run)
Mercury
1
Dziękuję Ci. Używam Pythona 3.5.2 na komputerze Mac. Wypróbowałem twój link. Oczywiście działa, chociaż nie wiem, dlaczego otrzymuję tę wiadomość. strfilter
4
@joshua Prawdopodobnie już to rozgryzłeś, ale spróbuj print(list(newlist))lubprint([i for i in newlist])
James Draper,
1
To jest absurdalnie trudne. Dlatego R jest lepszy. Po prostu grep (pattern, vector_of_names)
MadmanLee
1

Aby to zrobić bez najpierw kompilowania Regex, użyj lambdafunkcji - na przykład:

from re import match

values = ['123', '234', 'foobar']
filtered_values = list(filter(lambda v: match('^\d+$', v), values))

print(filtered_values)

Zwroty:

['123', '234']

filter()po prostu przyjmuje callablejako pierwszy argument i zwraca listę, na której ten wywoływany zwrócił wartość „prawdziwą”.

Collin Heist
źródło