любая () функция в Python с обратным вызовом - PullRequest
57 голосов
/ 06 января 2010

Стандартная библиотека Python определяет функцию any(), которая

Возвращает True, если какой-либо элемент итерируемого равен true. Если итерация пуста, вернуть False.

Проверяется, только если элементы оцениваются в True. То, что я хочу, чтобы это было в состоянии, поэтому укажите обратный вызов, чтобы сказать, соответствует ли элемент счета как:

any([1, 2, 'joe'], lambda e: isinstance(e, int) and e > 0)

Ответы [ 8 ]

102 голосов
/ 06 января 2010

Как насчет:

>>> any(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
True

Также работает с all(), конечно:

>>> all(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
False
19 голосов
/ 06 января 2010

любая функция возвращает 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.

На самом деле, концепция любой функции взята из Lisp или, можно сказать, из подхода функционального программирования. Есть еще одна функция, которая прямо противоположна ей: 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.

Эти две функции действительно хороши при правильном использовании.

8 голосов
/ 06 января 2010

Вы должны использовать «выражение-генератор», то есть языковую конструкцию, которая может использовать итераторы и применять фильтр и выражения к одной строке:

Например, (i ** 2 for i in xrange(10)) - это генератор для квадрата первых 10 натуральных чисел (от 0 до 9)

Они также позволяют предложению «if» фильтровать itens по предложению «for», поэтому для вашего примера вы можете использовать:

any (e for e in [1, 2, 'joe'] if isinstance(e, int) and e > 0)
6 голосов
/ 14 марта 2014

Незначительное улучшение к ответу Антуана Р

>>> any(type(e) is int for e in [1,2,'joe'])
True

Для all()

>>> all(type(e) is int for e in [1,2,'joe'])
False
5 голосов
/ 09 ноября 2013

В то время как другие дали хорошие Pythonic ответы (я просто использовал принятый ответ в большинстве случаев), я просто хотел указать, как легко сделать свою собственную функцию полезности, чтобы сделать это самостоятельно, если вы действительно этого хотите:

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

Я думаю, что сначала я бы по крайней мере определил его с параметром функции, так как он бы более точно соответствовал существующим встроенным функциям, таким как map () и filter ():

def any_lambda(function, iterable):
  return any(function(i) for i in iterable)
2 голосов
/ 09 февраля 2015

Вы можете использовать комбинацию any и map, если вы действительно хотите сохранить свою лямбда-нотацию следующим образом:

any(map(lambda e: isinstance(e, int) and e > 0, [1, 2, 'joe']))

Но лучше использовать выражение генератора, потому что оно не построит весь список дважды.

2 голосов
/ 06 января 2010

фильтр может работать, плюс он возвращает вам соответствующие элементы

>>> filter(lambda e: isinstance(e, int) and e > 0, [1,2,'joe'])
[1, 2]
0 голосов
/ 02 августа 2017

Если вы действительно хотите вставить лямбду в любой (), вы можете сделать это:

>>> any((lambda: isinstance(e, int))() for e in [1,2,'joe'])
True
>>> any((lambda: isinstance(e, int))() for e in ['joe'])
False

Вам просто нужно обернуть безымянную лямбду и убедиться, что она вызывается при каждом проходе, добавив ()

Преимущество здесь в том, что вы все равно можете воспользоваться коротким замыканием оценки любого, когда вы нажмете первый int

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...