Як саме працює будь-яка () функція пітона?


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?

Відповіді:


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значення.


25
Варто також згадати, що any(x > 0 for x in list)це лише синтаксичний цукор для any((x > 0 for x in list)).
georg

3
Вам слід додати Noneдо списку елементів, що мають булеві значенняFalse
Alok Mysore

2
Якщо додати до @georg, синтаксичний цукор не особливий any. def b(x): return x; print b(x > 1 for x in xs) # prints <generator object ..
промисловість

@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

Простіше кажучи, будь-який () робить це так: згідно з умовою, навіть якщо у списку зустрічається одне виконуюче значення, воно повертає істину, інакше повертає помилкове.

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.