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

218

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 façon la plus élégante de faire cela en Python (sans utiliser la boucle for)? Je pensais à quelque chose comme ça (comme en C / C ++), mais cela n'a pas fonctionné:

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

Edit: je suis un peu obligé d'expliquer en quoi cela est différent de la question ci-dessous qui est marquée comme doublon potentiel (donc elle ne se ferme pas, je suppose).

La différence est que je voulais vérifier si une chaîne fait partie d'une liste de chaînes alors que l'autre question consiste à vérifier si une chaîne d'une liste de chaînes est une sous-chaîne d'une autre chaîne. Similaire, mais pas tout à fait la même chose et la sémantique importe lorsque vous recherchez une réponse en ligne à mon humble avis. 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 cependant la même.

pootzko
la source
4
Copie

Réponses:

423

Utilisez un générateur avec anylequel 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 une solution "assez bonne" à son problème particulier et constitue un bon moyen général de vérifier si des chaînes d'une liste se trouvent dans une autre chaîne, gardez à l'esprit que c'est tout ce que fait cette solution. Peu importe où se trouve la chaîne, par exemple à la fin de la chaîne . Si cela est important, comme c'est souvent le cas avec les URL, vous devriez chercher la réponse de @Wladimir Palant, sinon vous risquez d'obtenir des faux positifs.

Lauritz V. Thaulow
la source
1
c'était exactement ce que je cherchais. dans mon cas, peu importe où dans la chaîne se trouve l'extension. merci
pootzko
Grande suggestion. En utilisant cet exemple, voici comment je vérifie si l'un des arguments correspond aux indicateurs d'aide bien connus: any ([x.lower () in ['-?', '- h', '- help', '/ h '] pour x dans sys.argv [1:]])
AX Labs
@ AX-Labs utilisant des compréhensions de liste à l'intérieur anyannulera certains des gains possibles que fournit le court-circuit, car la liste entière devra être construite dans tous les cas. Si vous utilisez l'expression sans crochets ( any(x.lower() in ['-?','-h','--help', '/h'] for x in sys.argv[1:])), la x.lower() in [...]pièce sera évaluée uniquement jusqu'à ce qu'une valeur True soit trouvée.
Lauritz V. Thaulow
5
Et si je veux savoir ce qu'est ext quand any () renvoie True?
Peter Senna
@PeterSenna: any()ne renverra que vrai ou faux , mais voir la réponse de compréhension de liste de @psun ci-dessous avec cette modification:print [extension for extension in extensionsToCheck if(extension in url_string)]
Dannid
45
extensionsToCheck = ('.pdf', '.doc', '.xls')

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

'test.jpg'.endswith(extensionsToCheck)   # returns False
eumiro
la source
5
celui-ci est intelligent - je ne savais pas que les tuples pouvaient faire ça !, mais cela ne fonctionne que lorsque votre sous-chaîne est ancrée à une extrémité de la chaîne.
Dannid
3
Vraiment cool. Je souhaite juste qu'il y ait quelque chose comme "contient" plutôt que de commencer ou de terminer avec
BrDaHa
@BrDaHa, vous pouvez utiliser 'in' pour contient. si 'string' dans la liste:
Shekhar Samanta
@ShekharSamanta bien sûr, mais cela ne résout pas le problème de vérifier si l'une des multiples choses est dans une chaîne, c'est-à-dire que la question d'origine était sur le point.
BrDaHa
Oui, dans ce cas, nous pouvons utiliser: le cas échéant (élément dans string.split ('tout séparateur') pour élément dans la liste) & pour la chaîne le cas échéant (élément dans la chaîne pour l'élément dans la liste)
Shekhar Samanta
21

Il est préférable d'analyser correctement l'URL - de cette façon, vous pouvez gérer http://.../file.doc?fooet http://.../foo.doc/file.execorrectement.

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

Utilisez des listes de compréhension si vous voulez une solution sur une seule ligne. Le code suivant retourne une liste contenant la chaîne url lorsqu'elle a les extensions .doc, .pdf et .xls ou renvoie une liste vide lorsqu'elle ne contient pas l'extension.

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

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

psun
la source
C'est plus lisible que la anysolution, c'est l'une des meilleures solutions possibles pour cette question à mon avis.
Dmitry Verhoturov
Celui-ci est supérieur à la any()solution à mon avis, car il peut également être modifié pour renvoyer la valeur de correspondance spécifique, comme ceci: print [extension for extension in extensionsToCheck if(extension in url_string)](voir ma réponse pour plus de détails et comment extraire le mot correspondant ainsi que le modèle de la chaîne url)
Dannid
2

Vérifiez s'il correspond à cette expression régulière:

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

Remarque: si vos extensions ne sont pas à la fin de l'url, supprimez les $caractères, mais cela l'affaiblit légèrement


la source
1
C'est une URL, et si elle a une chaîne de requête?
Wladimir Palant
import re re.search (pattern, your_string)
juankysmith
bien que cette réponse fonctionne pour le cas spécifié, elle n'est ni évolutive ni générique. vous auriez besoin d'une expression régulière longue pour chaque motif que vous souhaitez faire correspondre.
Dannid
1

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

En changeant la valeur de sortie, vous pouvez réellement extraire le modèle de correspondance de la compréhension de la liste (chose impossible avec l' any()approche 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 motif correspondant est connu (cela pourrait être utile lorsque la liste des motifs autorisés est trop longue pour être écrite dans un seul motif d'expression régulière)

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

['foo.doc']

Dannid
la source