La bibliothèque standard Python définit une fonction any()
qui
Renvoie True si l'un des éléments de l'itérable est true. Si l'itérable est vide, retournez False.
Il vérifie uniquement si les éléments sont évalués à True
. Ce que je veux, c'est pouvoir ainsi spécifier un rappel pour dire si un élément convient à la facture comme:
any([1, 2, 'joe'], lambda e: isinstance(e, int) and e > 0)
Que diriez-vous:
>>> any(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
True
Cela fonctionne aussi avec all()
bien sûr:
>>> all(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
False
La fonction any renvoie True lorsque l'une des conditions est True.
>>> any(isinstance(e, int) and e > 0 for e in [0 ,0, 1])
True # Returns True because 1 is greater than 0.
>>> any(isinstance(e, int) and e > 0 for e in [0 ,0, 0])
False # Returns False because not a single condition is True.
En fait, le concept de la fonction any provient de LISP ou de l’approche de programmation par fonctions. Il y a une autre fonction qui est juste en face d'elle all
>>> all(isinstance(e, int) and e > 0 for e in [1, 33, 22])
True # Returns True when all the condition satisfies.
>>> all(isinstance(e, int) and e > 0 for e in [1, 0, 1])
False # Returns False when a single condition fails.
Ces deux fonctions sont vraiment chouettes lorsqu'elles sont utilisées correctement.
Vous devez utiliser une "expression de générateur", c'est-à-dire une construction de langage pouvant consommer des itérateurs et appliquer un filtre et des expressions sur une seule ligne:
Par exemple, (i ** 2 for i in xrange(10))
est un générateur pour le carré des 10 premiers nombres naturels (0 à 9)
Ils permettent également à une clause "if" de filtrer les informations sur la clause "pour", ainsi, pour votre exemple, vous pouvez utiliser:
any (e for e in [1, 2, 'joe'] if isinstance(e, int) and e > 0)
Légère amélioration de la réponse d'Antoine P.
>>> any(type(e) is int for e in [1,2,'joe'])
True
Pour all()
>>> all(type(e) is int for e in [1,2,'joe'])
False
Tandis que les autres donnaient de bonnes réponses Pythonic (je n'utiliserais que la réponse acceptée dans la plupart des cas), je voulais simplement souligner combien il est facile de créer votre propre fonction utilitaire pour le faire vous-même si vous le préférez vraiment:
def any_lambda(iterable, function):
return any(function(i) for i in iterable)
In [1]: any_lambda([1, 2, 'joe'], lambda e: isinstance(e, int) and e > 0
Out[1]: True
In [2]: any_lambda([-1, '2', 'joe'], lambda e: isinstance(e, int) and e > 0)
Out[2]: False
Je pense au moins que je le définirais d'abord avec le paramètre function, car cela correspondrait plus étroitement aux fonctions intégrées existantes telles que map () et filter ():
def any_lambda(function, iterable):
return any(function(i) for i in iterable)
le filtre peut fonctionner, en plus il vous renvoie les éléments correspondants
>>> filter(lambda e: isinstance(e, int) and e > 0, [1,2,'joe'])
[1, 2]
Vous pouvez utiliser une combinaison de any
et map
si vous voulez vraiment conserver votre notation lambda comme suit:
any(map(lambda e: isinstance(e, int) and e > 0, [1, 2, 'joe']))
Mais il est préférable d’utiliser une expression génératrice car elle ne construira pas la liste complète deux fois.
Si vous vraiment voulez insérer un lambda dans un (), vous pouvez le faire:
>>> any((lambda: isinstance(e, int))() for e in [1,2,'joe'])
True
>>> any((lambda: isinstance(e, int))() for e in ['joe'])
False
Il vous suffit de terminer le lambda non nommé et de vous assurer qu'il est invoqué à chaque passe en ajoutant le ()
L’avantage ici est que vous continuez à profiter du court-circuit de l’évaluation de tout résultat lorsque vous frappez le premier int