Como funciona exatamente a função any () do python?

113

Na página de documentos do python para any, o código equivalente para a any()função é fornecido como:

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

Como essa função sabe qual elemento eu quero testar se chamá-lo desta forma?

any(x > 0 for x in list)

Pela definição da função, tudo o que posso ver é que estou passando um objeto iterável. Como o forloop sabe que estou procurando algo > 0?

pythoniku
fonte

Respostas:

166

Se você usar, any(lst)verá que lsté iterável, que é uma lista de alguns itens. Se contivesse [0, False, '', 0.0, [], {}, None](que todos têm valores booleanos de False), então any(lst)seria False. Se lsttambém contivesse qualquer um dos seguintes [-1, True, "X", 0.00001](todos avaliados como True), entãoany(lst) seria True.

No código que você postou, x > 0 for x in lsteste é um tipo diferente de iterável, chamado de expressão geradora . Antes gerador de expressões foram adicionados ao Python, você teria criado uma compreensão lista , que se parece muito semelhante, mas com áreas []de: [x > 0 for x in lst]. Do lstcontendo [-1, -2, 10, -4, 20], você teria esta lista compreendido : [False, False, True, False, True]. Este valor interno seria então passado para a anyfunção, que retornaria True, uma vez que há pelo menos umTrue valor.

Mas com expressões geradoras , o Python não precisa mais criar essa lista interna de True(s)e False(s), os valores serão gerados conforme a anyfunção itera por meio dos valores gerados um de cada vez pela expressão geradora. E , como anyocorre em curto-circuito, ele para de iterar assim que vê o primeiro Truevalor. Isso seria especialmente útil se você criou lstusando algo como lst = range(-1,int(1e9))(ou xrangese estiver usando Python2.x ). Mesmo que esta expressão gere mais de um bilhão de entradas, anysó precisa ir até a terceira entrada quando chegar a 1, que avalia Truepara x>0, e então anypode retornarTrue .

Se você tivesse criado uma compreensão de lista , Python teria primeiro que criar a lista de bilhões de elementos na memória e, em seguida, passá-la para any. Mas, usando uma expressão geradora , você pode ter as funções embutidas do Python como anye allaparecer mais cedo, assim que um valor Trueou Falsefor visto.

PaulMcG
fonte
25
Também vale a pena mencionar que any(x > 0 for x in list)é apenas um açúcar sintático para any((x > 0 for x in list)).
georg
3
Você deve adicionar Noneà lista de elementos que têm valores booleanos deFalse
Alok Mysore
2
Adicionando ao @georg, o açúcar sintático não é especial para any. def b(x): return x; print b(x > 1 for x in xs) # prints <generator object ..
industryworker3595112
@georg Obrigado por este esclarecimento. Este é um ponto muito importante que me confundiu ao testar o código com quaisquer colchetes.
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

Ele apenas reduz várias linhas de código em uma. Você não tem que escrever códigos longos como:

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

(x > 0 for x in list) nessa chamada de função cria uma expressão geradora, por exemplo.

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


True
True
False
True
False

Que anyusa, e atalhos ao encontrar o primeiro objeto que avaliaTrue

Jamylak
fonte
7

É porque o iterável é

(x > 0 for x in list)

Observe que x > 0retorna Trueou Falsee, portanto, você tem um iterável de booleanos.

esquisito
fonte
7

Simplesmente dizer, any () faz este trabalho: de acordo com a condição, mesmo se encontrar um valor de preenchimento na lista, ele retorna verdadeiro, caso contrário, ele retorna falso.

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
fonte