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

Причина "всего" и "любого" результата в пустых списках

В Python встроенные функции all и any возвращает True и False соответственно для пустых итераций. Я понимаю, что если бы все было наоборот, этот вопрос все равно можно было бы спросить. Но я хотел бы знать, почему это конкретное поведение было выбрано. Было ли это произвольным, т.е. может ли это так же легко было иначе, или есть основная причина?

(Причина, о которой я прошу, - это просто потому, что я никогда не помню, что это такое, и если бы я знал обоснование, то я мог бы. Кроме того, любопытство.)

4b9b3361

Ответ 1

Как насчет некоторых аналогов...

У вас есть ящик для носка, но он пуст. Он содержит черный носок? Нет - у вас совсем нет носков, поэтому у вас, конечно же, нет черного. Очевидно, что any([]) должен возвращать false - если он вернёт true, это будет контринтуитивно понятным.

Случай для all([]) немного сложнее. См. Статью Википедии о пустое правду. Другая аналогия: если в комнате нет людей, то все в этой комнате могут говорить по-французски.

Математически all([]) можно написать:

eb6ff3d273962bfadb292ad2a3c9fbd8.png, где множество A пусто.

Существует значительная дискуссия о том, следует ли считать пустое высказывание истинным или нет, но с логической точки зрения он имеет наибольший смысл:

Основной аргумент в пользу того, что все пустое истинное утверждение истинно, таков: Как объясняется в статье о логических условностях, аксиомы пропозициональных логика подразумевает, что если P ложно, то P = > Q истинно. То есть, если мы принимаем эти аксиомы, мы должны признать, что пустое истинное утверждение действительно истинно.

Также из статьи:

Кажется, нет прямой причины выбирать истину; это просто то, что на нас взорвутся, если мы этого не сделаем.

Определение оператора "vacuously true" для возврата false в Python нарушит принцип наименьшего удивления.

Ответ 2

Одним из свойств any является его рекурсивное определение

any([x,y,z,...]) == (x or any([y,z,...]))

Это означает

x == any([x]) == (x or any([]))

Равенство верно для любого x тогда и только тогда, когда any([]) определено как False. Аналогично для all.

Ответ 3

Я считаю, что all([])==True, как правило, сложнее понять, поэтому вот коллекция примеров, где я считаю, что поведение, очевидно, верно:

  • Фильм подходит для слушания, если все диалоги в фильме озаглавлены. Фильм без диалога по-прежнему подходит для слабослышащих.
  • Комната без окон темная, когда все огни внутри выключены. Когда внутри нет света, темно.
  • Вы можете пройти через безопасность в аэропорту, когда все ваши жидкости содержатся в бутылках по 100 мл. Если у вас нет жидкостей, вы все равно можете пройти через безопасность.
  • Вы можете поместить мягкий пакет через узкий слот, если все предметы в сумке уже, чем слот. Если сумка пуста, она все еще помещается в слот.
  • Задача готова к запуску, когда все ее предпосылки выполнены. Если задача не имеет предварительных условий, она готова к запуску.

Ответ 4

Я думаю, что они реализованы таким образом

def all(seq):
    for item in seq:
        if not item:
            return False
    return True

def any(seq):
    for item in seq:
        if item:
            return True
    return False

не уверены, что они реализованы таким образом, хотя

Ответ 5

Perl 6 также принимает позицию, что all() и any() в пустых списках должны служить нормальными базовыми блоками для их соответствующих операторов сокращения, и поэтому all() истинно, а any() - false.

То есть, all(a, b, c) эквивалентно [&] a, b, c, что эквивалентно a & b & c (сокращение на "junctive and", но вы можете игнорировать переходы и считать его логичным и для этого сообщения), а any(a, b, c) эквивалентно [|] a, b, c, что эквивалентно a | b | c (сокращение от "junctive or" operator - снова, вы можете притворяться, что это то же, что логично или ничего не пропало).

Любой оператор, который может иметь приложенное к нему сокращение, должен иметь определенное поведение при уменьшении 0 членов, и обычно это делается с помощью естественного элемента идентификации - например, [+]() (уменьшение сложения по нулевым членам) 0, поскольку 0 - аддитивное тождество; добавление нуля к любому выражению оставляет его неизменным. [*]() также равно 1, потому что 1 является мультипликативным тождеством. Мы уже говорили, что all эквивалентно [&], а any эквивалентно [|] - ну, истина есть и-тождество, а ложность - или-тождество - x, а True - x, а x или False - x. Это делает неизбежным, что all() должен быть истинным, а any() должен быть ложным.

Чтобы поместить его в совершенно другую (но практическую) перспективу, any является защелкой, которая начинается с false и становится истиной всякий раз, когда видит что-то истинное; all - это защелка, которая начинается с истины и становится ложной всякий раз, когда видит что-то ложное. Предоставление им аргументов не означает, что у них нет шансов изменить состояние, поэтому вы просто спрашиваете их, каково их состояние "по умолчанию".:)

Ответ 6

Для общего интереса здесь сообщение в блоге, в котором GvR предлагает любые/все с примерной реализацией, такой как gnibbler и quanifiers в ABC.

Ответ 7

any и all имеют такой же смысл в python, как и везде:

  • any истинно, если хотя бы одно верно.
  • all неверно, если хотя бы один не является истинным

Ответ 8

Это скорее комментарий, но код в комментариях работает не очень хорошо.

В дополнение к другим логическим основам для того, почему any() и all() работают так, как они, они должны иметь противоположные "базовые" случаи, чтобы это соотношение сохранялось:

all(x for x in iterable) == not any(not x for x in iterable)

Если iterable имеет нулевую длину, вышеуказанное значение должно оставаться истинным. Поэтому

all(x for x in []) == not any(not x for x in [])

что эквивалентно

all([]) == not any([])

И было бы очень удивительно, если бы any([]) было истинным.