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

Уменьшает() короткое замыкание на Python?

Если я это сделаю:

result = reduce(operator.and_, [False] * 1000)

Будет ли он остановлен после первого результата? (так как False & anything == False)

Аналогично:

result = reduce(operator.or_, [True] * 1000)
4b9b3361

Ответ 1

Это не так. Ваша альтернатива в этом случае any и all.

result = reduce(operator.and_, [False] * 1000)
result = reduce(operator.or_, [True] * 1000)

можно заменить на

result = all([False] * 1000)
result = any([True] * 1000)

которые делают короткое замыкание.

Результаты синхронизации показывают разницу:

In [1]: import operator

In [2]: timeit result = reduce(operator.and_, [False] * 1000)
10000 loops, best of 3: 113 us per loop

In [3]: timeit result = all([False] * 1000)
100000 loops, best of 3: 5.59 us per loop

In [4]: timeit result = reduce(operator.or_, [True] * 1000)
10000 loops, best of 3: 113 us per loop

In [5]: timeit result = any([True] * 1000)
100000 loops, best of 3: 5.49 us per loop

Ответ 2

Не только сокращает() не короткое замыкание, но и не может коротко замыкаться на всех элементах, которые уменьшаются, поскольку он учитывает только пункты по два за раз. Кроме того, он не имеет понятия об условиях, при которых функция используется в коротких замыканиях. (Было бы неплохо, если бы функции могли иметь свойство, указывающее на значение, при котором они начинают замыкаться, что reduce() может затем распознавать и использовать, но они этого не делают.)

Ответ 3

Возможно, это возможно (см. судьба сокращения), что альтернативное сокращение реализации будет хорошо работать.

Эта идея отлично сработала для меня, чтобы сделать вещи более прозрачными в дизайне.

def ipairs(seq):
    prev = None
    for item in seq:
        if prev is not None:
            yield (prev, item)
        prev = item

def iapply(seq, func):
    for a, b in ipairs(seq):
        yield func(a, b)

def satisfy(seq, cond):
    return all(iapply(seq, cond))

def is_uniform(seq):
    return satisfy(seq, lambda a, b: a == b)

Как вы видите, сокращение разбито на iapply < - ipairs.

Обратите внимание, что это не эквивалентно

def ireduce(seq, func):
    prev = None
    for item in seq:
        if prev is None:
            prev = item
        else:
            prev = func(prev, item)
    return prev

Ответ 4

Помните, что оценка короткого замыкания - это не всегда то, что вы хотите. По этой причине ошибка "фиксации" сократится до короткого замыкания. Например, недавно мне пришлось изменить использование функции all() для сокращения() при обработке списка форм в django: я хочу сообщить о любых проблемах is_valid(), а не только о первом.