Как именно работает функция python any ()?

113

На странице документации Python для anyэквивалентный код для any()функции представлен как:

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

Как эта функция узнает, какой элемент я хочу проверить, если вызвать его в этой форме?

any(x > 0 for x in list)

Из определения функции все, что я вижу, это то, что я передаю итерируемый объект. Как forцикл узнает, что я что-то ищу > 0?

pythoniku
источник

Ответы:

166

Если вы используете, any(lst)вы увидите, что lstэто итерация, которая представляет собой список некоторых элементов. Если бы он содержал [0, False, '', 0.0, [], {}, None](все они имеют логические значения False), то any(lst)был бы False. Если бы lstтакже содержалось что-либо из следующего [-1, True, "X", 0.00001](все из которых оцениваются True), тогда any(lst)было бы True.

В опубликованном вами коде x > 0 for x in lstэто другой тип итерации, называемый выражением генератора . Перед выражения генератора были добавлены в Python, вы бы создали список понимание , который очень похож, но с окружающими []«s: [x > 0 for x in lst]. Из lstсодержащего [-1, -2, 10, -4, 20], вы получите этот постиг список : [False, False, True, False, True]. Затем это внутреннее значение будет передано anyфункции, которая вернется True, поскольку есть хотя бы одно Trueзначение.

Но с выражениями генератора Python больше не должен создавать этот внутренний список True(s)и False(s), значения будут генерироваться по мере того, как anyфункция выполняет итерацию по значениям, генерируемым по одному выражением генератора. И , поскольку происходит anyкороткое замыкание, он прекратит итерацию, как только увидит первое Trueзначение. Это будет особенно удобно, если вы создали lstчто-то вроде lst = range(-1,int(1e9))(или xrangeиспользуете Python2.x ). Несмотря на то, что это выражение сгенерирует более миллиарда записей, anyему нужно пройти только до третьей записи, когда она дойдет до 1, которая вычисляет Trueдля x>0и поэтому anyможет возвращаться True.

Если бы вы создали представление списка , Python сначала пришлось бы создать список из миллиардов элементов в памяти, а затем передать его в any. Но, используя выражение генератора , вы можете получить встроенные функции Python, такие как anyи all, преждевременное прерывание, как только будет обнаружено значение Trueили False.

PaulMcG
источник
25
Также стоит упомянуть, что any(x > 0 for x in list)это просто синтаксический сахар для any((x > 0 for x in list)).
georg
3
Вы должны добавить Noneв список элементов, которые имеют логические значенияFalse
Алок Майсор
2
Добавляя к @georg, синтаксический сахар не является особенным any. def b(x): return x; print b(x > 1 for x in xs) # prints <generator object ..
industryworker3595112
@georg Спасибо за это разъяснение. Это действительно важный момент, который меня смутил при тестировании кода с любыми скобками.
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

Он просто сокращает несколько строк кода в одну. Вам не нужно писать длинный код вроде:

for n in names:
    if n in 'King and john':
       print True
    else:
       print False
Пранджай Капаруван
источник
23

(x > 0 for x in list) в этом вызове функции создается выражение генератора, например.

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


True
True
False
True
False

Который anyиспользует, и короткие замыкания при обнаружении первого объекта, который оцениваетTrue

Джамылак
источник
7

Это потому, что итерация

(x > 0 for x in list)

Обратите внимание, что x > 0возвращает либо Trueили, Falseи, следовательно, у вас есть итерация логических значений.

причудливый
источник
7

Проще говоря, any () выполняет эту работу: в соответствии с условием, даже если он встречает одно выполняющее значение в списке, он возвращает true, иначе он возвращает 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
Алиша
источник