@MAGistr_MTM
Учусь программировать

Странное поведение встроенной функции. Не правда ли?

Доброго времени суток.

Недавно наткнулся на довольно странный результат выполнения стандартной функции:
any([]) == False
all([]) == True

Меня это немного смутило, и в документации вияснилось, что:
def all(iterable):
    for element in iterable:
        if not element:
            return False
    return True

Кто-нибудь может сказать, почему было решено для пустого объекта возвращать True?
  • Вопрос задан
  • 381 просмотр
Пригласить эксперта
Ответы на вопрос 3
@deliro
С первого взгяда может показаться нелогичным, но логика здесь есть.

Когда используется all? Когда мы проверяем, что все переменные в iterable-объекте - True (неважно, какого вида). Сформулировав по-другому, можно сказать: "all сообщает о том, что в списке все объекты не False". Т.к. Список пуст - значит в нём нет объектов, которые есть False.

С any похожая логика. "any сообщает о том, что в списке есть хотя бы один элемент True". Т.к. список пуст - значит в нём нет хотя бы одного объекта, который True.
Ответ написан
@nirvimel
В документации реализация этих функций записана в императивном стиле видимо для наглядности (ИМХО, наглядность довольно спорная). Можно попробовать записать их в функциональном стиле - это не сложно (напомню, что all - это конъюнкция всех элементов списка/итератора, приведенных к логическому типу, а any - соответственно, дизъюнкция).
import operator

all = lambda xs: reduce(operator.__and__, map(bool, xs), True)
any = lambda xs: reduce(operator.__or__, map(bool, xs), False)

При такой записи сразу становятся очевидны причины соответствующего поведения на пустых списках.
Ответ написан
Комментировать
aRegius
@aRegius
Python Enthusiast
Функция all() использует оператор and, что, в свою очередь, соответствует математическому символу умножения ' * '. Функция any() - оператор or (математический символ сложения ' + ')

Любое что-то можно разбить на составляющие: Что-то и Ничто. Например, 5 = 5 + 0

Так вот, допустим, функция all() принимает аргументом Что-то (какое-либо True). Помня о том, что all() работает
с ' * ', мы можем разбить это True на True * 1. Т.е. в случае c функцией all() Ничто, получается, принимает значение 1/True.

Сооответственно, помня о том, что any() работает с ' + ', мы можем разбить это True на True + 0. Т.е. в случае c функцией any() Ничто, получается, принимает значение 0/False.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы