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)
Foi útil?

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top