Espressioni regolari: ricerca nell'elenco


91

Voglio filtrare le stringhe in un elenco in base a un'espressione regolare.

C'è qualcosa di meglio di [x for x in list if r.match(x)]?

Risposte:


116

Puoi creare un iteratore in Python 3.x o un elenco in Python 2.x usando:

filter(r.match, list)

Per convertire l' iteratore Python 3.x in un elenco, è sufficiente eseguirne il cast; list(filter(..)).


2
In realtà, le comprensioni delle liste sono solitamente preferite ai costrutti funzionali come filtro, riduzione, lambda, ecc.
Ivo van der Wijk

39
@Ivo: Di solito sono preferiti perché di solito sono più chiari e spesso più succinti. Tuttavia in questo caso la filterversione è perfettamente nitida e ha molto meno rumore.
sepp2k

9
cosa c'è r.matchqui?
rbatt

2
@rbatt r.matchè un metodo che, quando applicato a una determinata stringa, trova se la regex rcorrisponde a quella stringa (e restituisce un oggetto match corrispondente in tal caso, ma in questo caso non importa perché ci interessa solo se il risultato è veritiero)
sepp2k

175

Esempio completo (Python 3):
per Python 2.x guarda la nota sotto

import re

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

Stampe:

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

Nota:

Per gli sviluppatori Python 2.x, filterrestituisce già un elenco. In Python 3.x èfilter stato modificato per restituire un iteratore, quindi deve essere convertito inlist (per vederlo stampato bene).

Esempio di codice Python 3 Esempio di codice
Python 2.x


4
Ciao, quando eseguo il codice sopra, ottengo <filter object at 0x1057acda0>cosa sto facendo di sbagliato?

1
Secondo python docs (python 2.7.12): docs.python.org/2/library/functions.html#filter filter restituisce un elenco, non un oggetto. Puoi anche controllare quel codice: repl.it/X3G/5786 (basta premere run)
Mercury

1
Grazie. Sto usando Python 3.5.2 su un Mac. Ho provato il tuo collegamento. Ovviamente funziona, anche se non sono sicuro del motivo per cui ricevo quel messaggio. Ho anche rimosso il strdato che filterrestituisce comunque un elenco, senza alcun risultato ...

4
@joshua probabilmente l'hai capito, ma prova print(list(newlist))oprint([i for i in newlist])
James Draper

1
Questo è incredibilmente difficile. Questo è il motivo per cui R è superiore. Semplicemente grep (pattern, vector_of_names)
MadmanLee

1

Per farlo senza compilare prima il Regex, usa una lambdafunzione, ad esempio:

from re import match

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

print(filtered_values)

Ritorna:

['123', '234']

filter()prende solo un callablecome primo argomento e restituisce un elenco in cui quel chiamabile ha restituito un valore "true".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.