Comment fonctionne exactement la fonction python any ()?

113

Dans la page de documentation python pour any, le code équivalent pour la any()fonction est donné comme suit:

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

Comment cette fonction sait-elle quel élément je veux tester si je l'appelle sous cette forme?

any(x > 0 for x in list)

À partir de la définition de la fonction, tout ce que je peux voir, c'est que je passe un objet itérable. Comment la forboucle sait-elle que je cherche quelque chose > 0?

pythoniku
la source

Réponses:

166

Si vous utilisez, any(lst)vous voyez que lstc'est l'itérable, qui est une liste de certains éléments. S'il contenait [0, False, '', 0.0, [], {}, None](qui ont tous des valeurs booléennes de False), alors le any(lst)serait False. S'il lstcontenait également l'un des éléments suivants [-1, True, "X", 0.00001](dont tous évalués à True), alors le any(lst)serait True.

Dans le code que vous avez publié, x > 0 for x in lstil s'agit d'un autre type d'itérable, appelé expression de générateur . Avant expressions du générateur ont été ajoutées à Python, vous avez créé une compréhension de la liste , ce qui est très similaire, mais avec autour []de: [x > 0 for x in lst]. De la lstcontenant [-1, -2, 10, -4, 20], vous obtiendrez cette liste compris : [False, False, True, False, True]. Cette valeur interne serait ensuite transmise à la anyfonction, qui retournerait True, car il y a au moins une Truevaleur.

Mais avec les expressions génératrices , Python n'a plus à créer cette liste interne de True(s)et False(s), les valeurs seront générées au fur et à mesure que la anyfonction parcourt les valeurs générées une par une par l'expression du générateur. Et , depuis les anycourts-circuits, il arrêtera d'itérer dès qu'il verra la première Truevaleur. Ce serait particulièrement pratique si vous avez créé en lstutilisant quelque chose comme lst = range(-1,int(1e9))(ou xrangesi vous utilisez Python2.x ). Même si cette expression générera plus d'un milliard d'entrées, elle anyn'a qu'à aller jusqu'à la troisième entrée lorsqu'elle arrive 1, qui évalue Truepour x>0, et anypeut donc revenir True.

Si vous aviez créé une compréhension de liste , Python aurait d'abord dû créer la liste d'un milliard d'éléments en mémoire, puis la transmettre à any. Mais en utilisant une expression de générateur , vous pouvez avoir des fonctions intégrées de Python comme anyet allse déclencher tôt, dès qu'une valeur Trueou Falseest vue.

PaulMcG
la source
25
Il serait également intéressant de mentionner que ce any(x > 0 for x in list)n'est qu'un sucre syntaxique pour any((x > 0 for x in list)).
georg
3
Vous devriez ajouter Noneà la liste des éléments qui ont des valeurs booléennes deFalse
Alok Mysore
2
En ajoutant à @georg, le sucre syntaxique n'est pas spécial pour any. def b(x): return x; print b(x > 1 for x in xs) # prints <generator object ..
industryworker3595112
@georg Merci pour cette clarification. C'est un point vraiment important qui m'a confus lors du test du code avec des crochets.
MasayoMusic
39
>>> names = ['King', 'Queen', 'Joker']
>>> any(n in 'King and john' for n in names)
True

>>> all(n in 'King and Queen' for n in names)
False

Il suffit de réduire plusieurs lignes de code en une seule. Vous n'avez pas besoin d'écrire du code long comme:

for n in names:
    if n in 'King and john':
       print True
    else:
       print False
Pranjay Kaparuwan
la source
23

(x > 0 for x in list) dans cette fonction, l'appel crée une expression de générateur, par exemple.

>>> nums = [1, 2, -1, 9, -5]
>>> genexp = (x > 0 for x in nums)
>>> for x in genexp:
        print x


True
True
False
True
False

Qui anyutilise et court-circuite à la rencontre du premier objet qui évalueTrue

Jamylak
la source
7

C'est parce que l'itérable est

(x > 0 for x in list)

Notez que x > 0retourne soit Trueou Falseet donc vous avez un itérable de booléens.

bizarre
la source
7

Dire simplement, any () fait ce travail: selon la condition, même s'il rencontre une valeur satisfaisante dans la liste, il retourne true, sinon il retourne false.

list = [2,-3,-4,5,6]

a = any(x>0 for x in lst)

print a:
True


list = [2,3,4,5,6,7]

a = any(x<0 for x in lst)

print a:
False
Alisha
la source