10
votes

Liste du filtrage et de la transformation

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: xxx

qui produit la liste suivante: xxx

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?


0 commentaires

8 Réponses :


19
votes

Que diriez-vous d'une compréhension de la liste? XXX


0 commentaires

5
votes

Vous pouvez le faire:

matches = [regex.match(l) for l in line]
versions = [m.group(1) for m in matches if m]


0 commentaires

0
votes

Vous n'avez pas vraiment besoin de vous embêter avec regex pour votre cas simple xxx

vérifiant davantage pour obtenir ceux avec "points".


0 commentaires

1
votes

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.


0 commentaires

0
votes

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']


0 commentaires

0
votes

Une façon dont je pouvais penser était de combiner la "carte" et la compréhension de la liste.
La solution semble ci-dessous:

xxx


0 commentaires

8
votes

Une autre doublure juste pour montrer d'autres manières (j'ai aussi nettoyé Regexp un peu): xxx

mais note que votre version originale est plus lisible que toutes les suggestions. Vaut-il la peine de changer?


2 commentaires

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.



0
votes

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']
  • Noms L'évaluation de motif.Match (lib) code> en tant que variable correspondant code> (qui est soit Aucun code> ou un RE. Match code> objet) li>
  • utilise ce correspondant code> EXPRESSION nommé en place ( Aucun code> ou a correspondant code>) pour filtrer les éléments non correspondants li>
  • et réutilisation correspondez code> dans la valeur mappée en extrayant le premier groupe ( match.group (1) code>). Li> ul> p>


0 commentaires