Expressions régulières: rechercher dans la liste

87

Je souhaite filtrer les chaînes dans une liste basée sur une expression régulière.

Y a-t-il quelque chose de mieux que [x for x in list if r.match(x)]?

Leoluk
la source

Réponses:

114

Vous pouvez créer un itérateur en Python 3.x ou une liste en Python 2.x en utilisant:

filter(r.match, list)

Pour convertir l' itérateur Python 3.x en liste, il suffit de le convertir ; list(filter(..)).

sepp2k
la source
2
En fait, les compréhensions de liste sont généralement préférées aux constructions fonctionnelles telles que filtre, réduction, lambda, etc.
Ivo van der Wijk
37
@Ivo: Ils sont généralement préférés car ils sont généralement plus clairs et souvent plus succincts. Cependant dans ce cas, la filterversion est parfaitement claire et a beaucoup moins de bruit.
sepp2k
9
qu'y a- r.matcht-il ici?
rbatt
2
@rbatt r.matchest une méthode qui, lorsqu'elle est appliquée à une chaîne donnée, trouve si l'expression régulière rcorrespond à cette chaîne (et renvoie un objet de correspondance correspondant si c'est le cas, mais cela n'a pas d'importance dans ce cas car nous nous soucions simplement de savoir si le résultat est véridique)
sepp2k
167

Exemple complet (Python 3):
Pour Python 2.x, regardez la note ci-dessous

import re

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

Impressions:

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

Remarque:

Pour les développeurs Python 2.x, filterrenvoie déjà une liste. En Python 3.x afilter été modifié pour renvoyer un itérateur, il doit donc être converti enlist (afin de le voir bien imprimé).

Exemple de code Python 3 Exemple de code
Python 2.x

Mercure
la source
4
Salut, Quand j'exécute le code ci-dessus, j'obtiens <filter object at 0x1057acda0>Qu'est-ce que je fais de mal?
1
Selon la documentation python (python 2.7.12): docs.python.org/2/library/functions.html#filter filter renvoie une liste et non un objet. Vous pouvez également vérifier ce code: repl.it/X3G/5786 (appuyez simplement sur exécuter)
Mercury
1
Merci. J'utilise Python 3.5.2 sur un Mac. J'ai essayé votre lien. Bien sûr, cela fonctionne, mais je ne sais pas pourquoi je reçois ce msg. J'ai même supprimé le strdepuis filterrenvoie une liste de toute façon, en vain ...
4
@joshua vous avez probablement déjà compris cela, mais essayez print(list(newlist))ouprint([i for i in newlist])
James Draper
1
C'est ridiculement difficile. C'est pourquoi R est supérieur. Simplement grep (pattern, vector_of_names)
MadmanLee
1

Pour ce faire sans compiler le Regex au préalable, utilisez une lambdafonction - par exemple:

from re import match

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

print(filtered_values)

Retour:

['123', '234']

filter()prend juste a callablecomme premier argument, et retourne une liste où cet appelable a renvoyé une valeur «véridique».

Collin Heist
la source