web-dev-qa-db-fra.com

Comment vérifier si une chaîne contient un élément d'une liste dans Python

J'ai quelque chose comme ça:

extensionsToCheck = ['.pdf', '.doc', '.xls']

for extension in extensionsToCheck:
    if extension in url_string:
        print(url_string)

Je me demande quelle serait la manière la plus élégante de faire cela en python (sans utiliser la boucle for)? Je pensais à quelque chose comme ça (comme à partir de c/c ++), mais ça ne marchait pas:

if ('.pdf' or '.doc' or '.xls') in url_string:
    print(url_string)

Edit: je suis un peu obligé d'expliquer en quoi c'est différent de la question ci-dessous qui est marquée comme une duplication potentielle (pour que ça ne soit pas fermé je suppose)).

La différence est que je voulais vérifier si une chaîne faisait partie d'une liste de chaînes alors que l'autre question consistait à vérifier si une chaîne d'une liste de chaînes était une sous-chaîne d'une autre chaîne. Similaires, mais pas tout à fait les mêmes. La chose et la sémantique importent quand vous cherchez une réponse à l’imho en ligne. Ces deux questions cherchent en fait à résoudre le problème opposé l’une de l’autre. La solution pour les deux s'avère être la même.

168
pootzko

Utilisez un générateur avec any, qui court-circuite sur le premier True:

if any(ext in url_string for ext in extensionsToCheck):
    print(url_string)

EDIT: Je vois que cette réponse a été acceptée par OP. Bien que ma solution puisse être "assez bonne" pour son problème particulier et constitue un bon moyen général de vérifier si des chaînes dans une liste se trouvent dans une autre chaîne, gardez à l'esprit que c'est tout ce que cette solution permet. Peu importe où la chaîne est trouvée, par exemple dans la fin de la chaîne. Si cela est important, comme c'est souvent le cas avec les URL, vous devriez rechercher la réponse de @Wladimir Palant, sinon vous risquez d'obtenir de faux positifs.

323
Lauritz V. Thaulow
extensionsToCheck = ('.pdf', '.doc', '.xls')

'test.doc'.endswith(extensionsToCheck)   # returns True

'test.jpg'.endswith(extensionsToCheck)   # returns False
34
eumiro

Il est préférable d’analyser correctement l’URL - de cette façon, vous pourrez gérer http://.../file.doc?foo et http://.../foo.doc/file.exe correctement.

from urlparse import urlparse
import os
path = urlparse(url_string).path
ext = os.path.splitext(path)[1]
if ext in extensionsToCheck:
  print(url_string)
17
Wladimir Palant

Utilisez les listes de compréhension si vous voulez une solution à une seule ligne. Le code suivant renvoie une liste contenant la chaîne_url lorsqu'il porte les extensions .doc, .pdf et .xls ou renvoie une liste vide lorsqu'il ne contient pas l'extension.

print [url_string for extension in extensionsToCheck if(extension in url_string)]

NOTE: Ceci est seulement pour vérifier s'il contient ou non et n'est pas utile quand on veut extraire le mot exact correspondant aux extensions.

2
psun

Vérifiez si cela correspond à cette expression rationnelle:

'(\.pdf$|\.doc$|\.xls$)'

Remarque: si vos extensions ne sont pas à la fin de l’URL, supprimez les caractères $, mais cela l’affaiblira légèrement.

2
user822535

Ceci est une variante de la réponse à la compréhension de liste donnée par @psun.

En changeant la valeur de sortie, vous pouvez réellement extraire le motif correspondant de la compréhension de liste (chose impossible avec l'approche any() de @ Lauritz-v-Thaulow)

extensionsToCheck = ['.pdf', '.doc', '.xls']
url_string = 'http://.../foo.doc'

print [extension for extension in extensionsToCheck if(extension in url_string)]

['.doc'] `

Vous pouvez en outre insérer une expression régulière si vous souhaitez collecter des informations supplémentaires une fois que le modèle correspondant est connu (cela peut être utile lorsque la liste des modèles autorisés est trop longue pour être écrite dans un seul motif regex)

print [re.search(r'(\w+)'+extension, url_string).group(0) for extension in extensionsToCheck if(extension in url_string)]

['foo.doc']

1
Dannid