web-dev-qa-db-fra.com

Python a-t-il une manière plus propre d'exprimer "si x contient a | b | c | d ..."?

La façon Pythonique de vérifier si une chaîne x est une sous-chaîne de y est:

if x in y:

Recherche si x est équivalent à a, b, c, d, e, f ou g est également Pythonic:

if x in [a,b,c,d,e,f,g]:

Mais vérifier si une chaîne x contient soit a, b, c, d, e, f ou g semble maladroit:

if a in x or b in x or c in x or d in x or e in x or f in x or g in x

Existe-t-il une méthode plus Pythonic pour vérifier si une chaîne x contient un élément d'une liste?

Je sais qu'il est trivial d'écrire cela moi-même en utilisant une boucle ou en utilisant une expression régulière:

re.search('(dog|cat|bird|mouse|elephant|pig|cow)', x)

mais je me demandais s'il y avait une manière plus propre qui n'implique pas l'expression régulière.

72
tom

L'approche Pythonique serait d'utiliser any() :

if any(s in x for s in (a,b,c,d,e,f,g)):

De la documentation liée:

any ( itérable)

Renvoie True si un élément de itérable est vrai. Si l'itérable est vide, retournez False. Équivalent à:

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

Notez également que j'ai utilisé un tuple au lieu d'une liste ici. Si vos valeurs a-g sont prédéfinies, un Tuple serait en effet préféré. Voir: Les tuples sont-ils plus efficaces que les listes en Python?

118
arshajii
if any(q in x for q in [a,b,c,d,e,f,g]):

Je pense que c'est à peu près aussi court et Pythonic que vous pouvez l'obtenir.

26
jwodder

Un peu tard pour la fête, mais

not frozenset(x).isdisjoint(frozenset(y))

fonctionnerait, et pourrait être plus rapide (algorithmiquement, mais peut-être pas pour les cas de test plus petits).

10

sans utiliser any mais simplement max

def is_in(symbol, lst):
    return max([symbol in x for x in lst]) 

print is_in('a',['ae','br','tl'])
print is_in('c',['ae','br','tl'])

donne

>>> 
True
False
3
kiriloff