qualquer () função em python com um retorno de chamada
-
19-09-2019 - |
Pergunta
A biblioteca padrão python define um any()
função isso
Retorne verdadeiro se algum elemento do iterável for verdadeiro. Se o iterável estiver vazio, retorne falsa.
Ele verifica apenas se os elementos avaliarem para True
. O que eu quero que ele possa especificar um retorno de chamada para saber se um elemento se encaixa na conta como:
any([1, 2, 'joe'], lambda e: isinstance(e, int) and e > 0)
Solução
Que tal:
>>> any(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
True
Também funciona com all()
é claro:
>>> all(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
False
Outras dicas
algum A função retorna true quando qualquer condição é verdadeira.
>>> 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.
Na verdade, o conceito de algum A função é trazida do LISP ou você pode dizer na abordagem de programação da função. Há outra função que é oposta a isso tudo
>>> 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.
Essas duas funções são muito legais quando usadas corretamente.
Você deve usar uma "expressão do gerador" - ou seja, um construto de idioma que pode consumir iteradores e aplicar filtro e expressões em seguida em uma única linha:
Por exemplo (i ** 2 for i in xrange(10))
é um gerador para o quadrado dos 10 primeiros números naturais (0 a 9)
Eles também permitem que uma cláusula "se" filtre os itens na cláusula "para"; portanto, para o seu exemplo que você pode usar:
any (e for e in [1, 2, 'joe'] if isinstance(e, int) and e > 0)
Ligeira melhora da resposta de Antoine P
>>> any(type(e) is int for e in [1,2,'joe'])
True
Por all()
>>> all(type(e) is int for e in [1,2,'joe'])
False
Enquanto os outros deram boas respostas pitônicas (eu usaria a resposta aceita na maioria dos casos), eu só queria apontar como é fácil fazer com que sua própria função de utilidade faça isso você mesmo, se você realmente preferir:
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
Acho que eu o definiria pelo menos com o parâmetro da função primeiro, já que isso corresponderia a funções internas existentes como map () e filtro ():
def any_lambda(function, iterable):
return any(function(i) for i in iterable)
O filtro pode funcionar, além de retornar os elementos correspondentes
>>> filter(lambda e: isinstance(e, int) and e > 0, [1,2,'joe'])
[1, 2]
Você pode usar uma combinação de any
e map
Se você realmente deseja manter sua notação lambda assim:
any(map(lambda e: isinstance(e, int) and e > 0, [1, 2, 'joe']))
Mas é melhor usar uma expressão de gerador, pois não criará a lista inteira duas vezes.
Se você verdade Quer embunhar um lambda em qualquer () você pode fazer isso:
>>> any((lambda: isinstance(e, int))() for e in [1,2,'joe'])
True
>>> any((lambda: isinstance(e, int))() for e in ['joe'])
False
Você só precisa encerrar o lambda sem nome e garantir que ele seja invocado em cada passe, anexando o ()
A vantagem aqui é que você ainda aproveita o curto -circuito da avaliação de qualquer um quando você atinge o primeiro INT