Подробный гайд: Разбираем, почему all() в Python возвращает True - Часть 1
1. Что делает функция all()
Функция all() принимает итерируемый объект и возвращает True, если все элементы этого объекта истинны.
Упрощённо она работает так:
all([1, 2, 3]) # True
all([1, 0, 3]) # False
all([True, True]) # True
all([True, False]) # False
Эквивалентная реализация выглядит примерно так:
def my_all(iterable):
for element in iterable:
if not element:
return False
return True
То есть all():
- идёт по элементам;
- проверяет каждый элемент через
bool(element); - если встречает хотя бы один ложный элемент, сразу возвращает
False; - если дошла до конца и ложных элементов не было, возвращает
True.
2. Почему all([]) возвращает True
Самый частый вопрос:
all([]) # True
Почему? Потому что в пустой коллекции нет ни одного ложного элемента.
Функция all() отвечает на вопрос:
Есть ли хотя бы один ложный элемент?
Если элементов нет вообще, то и ложный элемент найти невозможно. Поэтому возвращается True. Это называется вакуумная истина или истина для пустого множества.
Пример из жизни:
Все ли люди в пустой комнате ростом выше 3 метров?
Людей нет, значит, контрпримера нет. Формально утверждение считается истинным.
То же самое в математической логике:
∀x ∈ S: P(x)
Если множество S пустое, утверждение истинно, потому что нет ни одного x, для которого условие P(x) нарушено.
Поэтому:
all([]) # True
all(()) # True
all("") # True
all(range(0)) # True
3. Что считается истинным, а что ложным
all() не проверяет, что элементы равны именно True. Он проверяет их через bool().
В Python ложными считаются, например:
False
None
0
0.0
0j
""
[]
()
{}
set()
range(0)
И объекты, у которых __bool__() возвращает False или __len__() возвращает 0. Всё остальное по умолчанию обычно истинно.
Примеры:
all([1, 2, 3]) # True
all([1, "", 3]) # False, потому что "" ложно
all([[], [1]]) # False, потому что [] ложно
all(["a", "b"]) # True, непустые строки истинны
all([0]) # False
all([None]) # False
all([object()]) # True, обычный объект по умолчанию истинен
Важно понимать:
all([1, 2, 3])
Означает не «все элементы равны», а:
bool(1) and bool(2) and bool(3)
То есть:
True and True and True
4. all() и строки
Строка — итерируемый объект, поэтому all() перебирает её символы.
all("abc") # True
Почему? Потому что строка "abc" перебирается как:
"a", "b", "c"
Каждый символ — непустая строка, а непустая строка истинна.
Поэтому:
all("abc") # True
all("a0c") # True
all("") # True
Но если проверять сами символы на какое-то условие:
all(ch.isdigit() for ch in "123") # True
all(ch.isdigit() for ch in "12a") # False
5. Правильное использование all() с условием
Часто all() используют не просто для проверки истинности элементов, а для проверки условия.
Например:
numbers = [2, 4, 6, 8]
all(x % 2 == 0 for x in numbers) # True
Это означает:
Все числа в списке чётные?
Под капотом генератор выдаёт:
True, True, True, True
И all() проверяет, что нет ни одного False.
Если есть хотя бы одно нечётное число:
numbers = [2, 3, 6, 8]
all(x % 2 == 0 for x in numbers) # False
6. Почему all() может неожиданно вернуть True
6.1. Пустой список
items = []
all(x > 0 for x in items) # True
Если элементов нет, условие не нарушено. Поэтому True.
Если вам нужно, чтобы для пустого списка результат был False, добавьте проверку:
items = []
bool(items) and all(x > 0 for x in items) # False
Или:
if items and all(x > 0 for x in items):
print("Все элементы положительны")
else:
print("Список пуст или есть неположительный элемент")
6.2. Неправильное условие внутри all()
Очень частая ошибка:
values = [1, 2, 3]
all(x == 1 or 2 for x in values)
Кажется, что это проверяет:
x == 1 или x == 2
Но на самом деле Python понимает выражение так:
(x == 1) or 2
То есть:
True or 2
или:
False or 2
А 2 — это истинное значение. Поэтому результат всегда будет истинным.
Проверим:
values = [1, 2, 3, 4, 5]
all(x == 1 or 2 for x in values) # True, хотя это ошибка
Правильно:
all(x == 1 or x == 2 for x in values)
Или лучше:
all(x in (1, 2) for x in values)
6.3. Проверка не того, чего вы хотели
Например:
passwords = ["admin", "password", "123456"]
all(passwords) # True
Это не проверяет сложность паролей. Это просто проверяет, что все строки непустые.
Если нужно проверить длину:
all(len(password) >= 8 for password in passwords)
6.4. Итератор уже был исчерпан
Если вы передаёте в all() итератор, который уже закончился, он может вернуть True.
Пример:
numbers = iter([1, 2, 3])
print(next(numbers)) # 1
print(next(numbers)) # 2
print(next(numbers)) # 3
all(x > 0 for x in numbers) # True
Почему True? Потому что итератор уже пуст. Элементов нет, значит, ложных элементов нет.
7. all() не требует, чтобы элементы были равны True
Вот этот момент часто вызывает путаницу:
all([1, "hello", [1, 2]]) # True
Почему? Потому что:
bool(1) # True
bool("hello") # True
bool([1, 2]) # True
all() не делает проверку:
element is True
Он делает проверку:
bool(element)
Поэтому:
all([True, 1, "a", [1]]) # True
Но:
all([True, 1, "", [1]]) # False
Мы делимся этой технической информацией, чтобы помочь вам в решении задач — используйте её с пониманием. Статья носит рекомендательный характер, поэтому, пожалуйста, применяйте описанные методы осмотрительно.