В Python, встроенных функциях all
и any
вернуть True
и False
соответственно для пустого iterables. Я понимаю, что, если это было наоборот, этот вопрос можно было бы все еще задать. Но я хотел бы знать, почему то определенное поведение было выбрано. Действительно ли это было произвольно, т.е. это, возможно, столь же легко был другой путь, или существует ли базовая причина?
(Причина, которую я спрашиваю, состоит просто в том, потому что я никогда не помню, который является, который, и если я знал объяснение позади нее затем, я мог бы. Кроме того, любопытство.)
Как насчет аналогий ...
У вас есть ящик для носков, но он сейчас пуст. В нем есть черный носок? Нет, у тебя совсем нет носков, так что уж точно не черных. Ясно, что any ([])
должен возвращать false - если он вернул true, это было бы нелогично.
Случай для all ([])
немного сложнее. См. Статью в Википедии о пустой истине .Другая аналогия: если в комнате нет людей, то все в этой комнате могут говорить по-французски.
Математически all ([])
можно записать:
где множество A пусто.
Существует много споров о том, следует ли считать пустые утверждения истинными или нет, но с логической точки зрения это имеет наибольший смысл:
Главный аргумент в пользу того, что все бессмысленно истинные утверждения верны, заключается в следующем: Как объясняется в В статье о логических условных выражениях аксиомы логики высказываний влекут за собой, что если P ложно, то P => Q истинно. То есть, если мы принимаем эти аксиомы, мы должны признать, что бессмысленно истинные утверждения действительно верны.
Также из статьи:
Кажется, нет прямой причины выбирать истину; просто вещи взорвутся нам в лицо, если мы этого не сделаем.
Определение «пусто истинного» оператора для возврата false в Python нарушит принцип наименьшего удивления .
Одним из свойств any
является его рекурсивное определение
any([x,y,z,...]) == (x or any([y,z,...]))
Это означает
x == any([x]) == (x or any([]))
Равенство верно для любых x
тогда и только тогда, когда any ([])
определяется как False. Аналогично все
.
Для общего интереса вот сообщение в блоге , в котором GvR предлагает все / все с примером реализации, например кванификаторами gnibbler и ссылками в ABC.
Я думаю, что они реализованы таким образом
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
, но не уверен, что они реализованы таким образом
any
и all
имеют то же значение в python, что и везде:
any
истинно, если хотя бы один из них истиненall
не истинно, если хотя бы один из них не истиненPerl 6 также придерживается позиции, что all()
и any()
для пустых списков должны служить вменяемыми базовыми случаями для соответствующих операторов сокращения, и поэтому all()
истинно, а any()
ложно.
То есть, all(a, b, c)
эквивалентно [&] a, b, c
, что эквивалентно a & b & c
(редукция на оператор "junctive and", но вы можете игнорировать junctive и считать его логическим and для этого поста), и any(a, b, c)
эквивалентен [|] a, b, c
, что эквивалентно a | b | c
(редукция на оператор "junctive or" - опять же, можно сделать вид, что это то же самое, что логическое or, ничего не упуская).
Любой оператор, к которому может быть применена редукция, должен иметь определенное поведение при сокращении 0-терминов, и обычно это делается с помощью естественного элемента тождества - например, [+]()
(сокращение сложения по нулевым терминам) равен 0, потому что 0 - это аддитивное тождество; добавление нуля к любому выражению оставляет его неизменным. [*]()
также равно 1, потому что 1 - мультипликативное тождество. Мы уже говорили, что все
эквивалентно [&]
, а любой
эквивалентен [|]
- так вот, истина есть и-тождество, а ложь есть или-тождество -- x и True есть x, а x или False есть x. Это делает неизбежным, что all()
должно быть истинным, а any()
- ложным.
Чтобы представить это в совершенно другой (но практической) перспективе, any
- это защелка, которая начинается с false и становится true всякий раз, когда видит что-то true; all
- это защелка, которая начинается с true и становится false всякий раз, когда видит что-то false. Не давать им аргументов означает не давать им возможности изменить состояние, так что вы просто спрашиваете их о том, каково их состояние "по умолчанию" :)