Подтвердить что ты не робот

Означает ли Python, если условия лениво?

Например, если у меня есть следующий оператор:

if( foo1 or foo2)
    ...
    ...

Если foo1 истинно, будет ли python проверять состояние foo2?

4b9b3361

Ответ 1

Да, Python лениво оценивает логические условия.

docs говорят,

Выражение x и y сначала оценивает x; если x является ложным, его значение равно вернулся; в противном случае y вычисляется, и полученное значение равно вернулся.

Выражение x или y сначала оценивает x; если x истинно, его значение равно вернулся; в противном случае y вычисляется, и полученное значение равно вернулся.

Ответ 2

Леность Python может быть подтверждена следующим кодом:

def foo():
    print('foo')
    return False

def bar():
    print('bar')
    return False

foo() and bar()         #Only 'foo' is printed

С другой стороны,

foo() or bar()

приведет к печати как "foo", так и "bar".

Ответ 3

and or - ленивый

& | не является ленивым

Ответ 4

Это не технически ленивая оценка, это короткое замыкание булевых выражений.

Ленивая оценка имеет несколько иную коннотацию. Например, истинная ленивая оценка, вероятно, позволит этому

def foo(arg) :
    print "Couldn't care less"

foo([][0])

Но Python этого не делает.

Python также хорош тем, что он "эхо" содержит логические аргументы. Например, an или condition возвращает либо первый аргумент "правдивый", либо последний аргумент (если все аргументы "ложны" ). An и условие обратное.

Итак, "аргумент эха" booleans означает

2 и [] и 1

имеет значение [] и

[] или 1 или 2

оценивается в 1

Ответ 5

Да, Python оценивает лениво, поэтому foo2 не будет проверяться.

Я использую это все время для захвата предметов из словарных объектов, если я не знаю, существует ли ключ:

if 'key' in mydict and mydict['key'] == 'heyyo!':
    do_stuff()

См. ответ @unutbu для более полного объяснения.

Ответ 6

Это действительно часть or, которая коротко замкнута:

>>> 1 or 1/0  #also 0 and 1/0
1
>>> 0 or 1/0  #also 1 and 1/0

Traceback (most recent call last):
  File "<pyshell#1240>", line 1, in <module>
    0 or 1/0
ZeroDivisionError: integer division or modulo by zero

Ответ 7

Коротким демо было бы сравнение разницы во времени между

all(xrange(1,1000000000))

и

any(xrange(1,1000000000))

Все() должны проверять каждое значение, в то время как any() может отказаться от первого True. Таким образом, xrange, будучи генератором, также отказывается от генерирующих вещей, как только выполняется оценщик. По этой причине все будет потреблять большие объемы оперативной памяти и получать возраст, в то время как любой из них будет использовать всего несколько байтов и мгновенно вернуться.