J'ai une liste de noms de fichiers de bibliothèque que je dois filtrer contre l'expression régulière, puis extraire le numéro de version de ceux qui correspondent. C'est la manière évidente de faire cela: qui produit la liste suivante: p> mais je pense que cette boucle n'est pas très " Style Python 'et estime qu'il devrait être possible de remplacer "pour" boucle ci-dessus avec une seule doublure intelligente.
Suggestions? P> p>
8 Réponses :
Que diriez-vous d'une compréhension de la liste?
Vous pouvez le faire:
matches = [regex.match(l) for l in line] versions = [m.group(1) for m in matches if m]
Vous n'avez pas vraiment besoin de vous embêter avec regex pour votre cas simple vérifiant davantage pour obtenir ceux avec "points". P> P>
Il n'y a rien qui n'est pas pythonique sur l'utilisation d'une norme pour la boucle. Cependant, vous pouvez utiliser le carte () fonction pour générer un nouveau liste basée sur les résultats d'une fonction exécutée contre chaque élément de la liste. p>
Que diriez-vous de celui-ci:
import re def matches(regexp, list): 'Regexp, [str] -> Iterable(Match or None)' return (regexp.match(s) for s in list) libs = ['libIce.so.33', 'libIce.so.3.3.1', 'libIce.so.32', 'libIce.so.3.2.0'] regexp = re.compile('libIce.so\.([0-9]+\.[0-9]+\.[0-9]+)') versions = [m.group(1) for m in matches(regexp, libs) if m is not None] >>> print versions ['3.3.1', '3.2.0']
Une façon dont je pouvais penser était de combiner la "carte" et la compréhension de la liste.
La solution semble ci-dessous:
p> p> p> code> p>
Une autre doublure juste pour montrer d'autres manières (j'ai aussi nettoyé Regexp un peu): mais note que votre version originale est plus lisible que toutes les suggestions. Vaut-il la peine de changer? P> p>
Merci pour "Findall" et "Somme"! En ce qui concerne la lisibilité - déjà habitué avec tous les algorithmes STL et Boost :)
Pour une raison quelconque, celui-ci fait beaucoup plus de sens pour moi que la réponse acceptée / upvote.
Démarrage Python 3.8 Code> et l'introduction de Expressions (Pep 572) (
: = code> opérateur), il est possible d'utiliser une variable locale dans une compréhension de la liste afin d'éviter d'appeler deux fois le résultat de la correspondance REGEX:
# libs = ['libIce.so.33', 'libIce.so.3.3.1', 'libIce.so.32', 'libIce.so.3.2.0']
# pattern = re.compile(r'libIce.so\.([0-9]+\.[0-9]+\.[0-9]+)')
[match.group(1) for lib in libs if (match := pattern.match(lib))]
# ['3.3.1', '3.2.0']
motif.Match (lib) code> en tant que variable
correspondant code> (qui est soit
Aucun code> ou un
RE. Match code> objet) li>
correspondant code> EXPRESSION nommé en place (
Aucun code> ou a
correspondant code>) pour filtrer les éléments non correspondants li>
correspondez code> dans la valeur mappée en extrayant le premier groupe (
match.group (1) code>). Li>
ul> p>