Подробный гайд: Разбираем, почему all() в Python возвращает True - Часть 2

Разбираем, почему all() в Python возвращает True: пустые итерируемые объекты, истинность элементов, частые ошибки и практические примеры.

2026.10.05                  


Подробный гайд: Разбираем, почему all() в Python возвращает True - Часть 2Подробный гайд: Разбираем, почему all() в Python возвращает True - Часть 2

8. all() и короткие замыкания

all() останавливается, как только находит первый ложный элемент.

Пример:

def check(x):
    print("Проверяю", x)
    return x

all(check(x) for x in [1, 2, 0, 3])

Вывод будет примерно таким:

Проверяю 1
Проверяю 2
Проверяю 0

До 3 дело не дойдёт, потому что 0 ложный, и all() сразу вернул False. Это важно для производительности и для работы с бесконечными последовательностями. Но если все элементы истинны, all() придётся дойти до конца.




9. Разница между all() и any()

  • all() возвращает True, если все элементы истинны.
  • any() возвращает True, если хотя бы один элемент истинен.

Таблица:

all([])    # True
any([])    # False

all([0])   # False
any([0])   # False

all([1])   # True
any([1])   # True

all([1, 0])  # False
any([1, 0])  # True

Логически:

all(iterable)

похоже на:

element_1 and element_2 and element_3 and ...

А:

any(iterable)

похоже на:

element_1 or element_2 or element_3 or ...

Для пустого списка:

all([])  # True, потому что нет ложных элементов
any([])  # False, потому что нет истинных элементов

10. Примеры из практики

Проверка, что все числа положительные

numbers = [1, 2, 3, 4]

all(x > 0 for x in numbers)  # True

Если список пуст:

numbers = []

all(x > 0 for x in numbers)  # True

Если нужно запретить пустой список:

numbers = []

if numbers and all(x > 0 for x in numbers):
    print("Все числа положительные")
else:
    print("Список пуст или есть неположительные числа")

Проверка, что все строки непустые

fields = ["Иван", "Иванов", "Москва"]

all(fields)  # True

Если хотя бы одна пустая строка:

fields = ["Иван", "", "Москва"]

all(fields)  # False

Проверка, что все строки содержат только цифры

codes = ["123", "456", "789"]

all(code.isdigit() for code in codes)  # True

Если есть нецифровая строка:

codes = ["123", "45a", "789"]

all(code.isdigit() for code in codes)  # False

Проверка, что все ключи существуют

data = {"name": "Иван", "age": 30}

required = ["name", "age"]

all(key in data for key in required)  # True

Если ключа не хватает:

required = ["name", "age", "email"]

all(key in data for key in required)  # False

Проверка, что все файлы существуют

from pathlib import Path

files = ["a.txt", "b.txt"]

all(Path(file).exists() for file in files)

Если список пуст, результат будет True.

Поэтому если файлов обязательно должен быть хотя бы один:

files = []

bool(files) and all(Path(file).exists() for file in files)

11. Частые ошибки

Ошибка 1: думать, что all([]) должен вернуть False

all([])  # True

Это не баг. Это логическое поведение: нет элементов — нет нарушений.

Если нужно, чтобы пустая коллекция считалась ошибкой:

if items and all(condition(x) for x in items):
    ...

Ошибка 2: передавать список вместо генератора, когда это не нужно

Можно писать так:

all([x > 0 for x in numbers])

Но лучше так:

all(x > 0 for x in numbers)

Почему?

Первый вариант создаёт весь список результатов в памяти:

[True, True, False, ...]

Второй вариант использует генератор и не создаёт лишний список целиком.


Ошибка 3: неправильно писать составное условие

Неправильно:

all(x == 1 or 2 for x in values)

Правильно:

all(x == 1 or x == 2 for x in values)

Или:

all(x in (1, 2) for x in values)

Ошибка 4: ожидать, что all() проверяет равенство элементов

all([5, 5, 5])  # True

Это не значит, что все элементы равны между собой. Это значит, что все элементы истинны.

Если нужно проверить, что все элементы равны:

values = [5, 5, 5]

all(x == values[0] for x in values)

Или безопаснее для пустого списка:

def all_equal(values):
    iterator = iter(values)

    try:
        first = next(iterator)
    except StopIteration:
        return True  # или False, если пустой список должен быть ошибкой

    return all(x == first for x in iterator)

12. Как проверить, что коллекция не пустая и все элементы истинны

Иногда нужно именно:



  1. чтобы элементы были;
  2. чтобы все они были истинны.

Простой вариант:

def all_and_not_empty(iterable):
    return bool(iterable) and all(iterable)

Но это работает не для всех итерируемых объектов. Например, генератор нельзя надёжно проверить через bool(), потому что генератор всегда истинен как объект.

Более универсальный вариант:

def all_and_not_empty(iterable):
    iterator = iter(iterable)

    try:
        first = next(iterator)
    except StopIteration:
        return False

    return bool(first) and all(iterator)

Примеры:

all_and_not_empty([])        # False
all_and_not_empty([1, 2])    # True
all_and_not_empty([1, 0])    # False
all_and_not_empty([0, 1])    # False

13. Почему all() может вернуть True в вашем коде: чек-лист

Если all() возвращает True, хотя вы ожидали False, проверьте:

1. Не пустой ли итерируемый объект?

   print(list(iterable))

2. Правильное ли условие внутри генератора?

   for x in iterable:
       print(x, condition(x))

3. Не используете ли вы конструкцию вроде:

   x == 1 or 2

вместо:

   x == 1 or x == 2
  1. Не передаёте ли вы уже исчерпанный итератор?
  2. Не проверяете ли вы просто истинность объектов, хотя хотели проверять их содержимое?
  3. Не ожидаете ли вы, что all() проверяет равенство элементов?

14. Короткий итог

all() возвращает True, если:

все элементы итерируемого объекта истинны

или если:

элементов нет вообще

Поэтому:

all([])  # True

Это нормально, потому что нет ни одного элемента, который был бы ложным.

Главная формула:

all(iterable) == True

означает:

не нашлось ни одного ложного элемента

А не:

элементы обязательно существуют

и не:

элементы равны True

Если вам нужно, чтобы пустая коллекция давала False, используйте проверку:

if iterable and all(condition(x) for x in iterable):
    ...

Мы делимся этой технической информацией, чтобы помочь вам в решении задач — используйте её с пониманием. Статья носит рекомендательный характер, поэтому, пожалуйста, применяйте описанные методы осмотрительно.


Статью подготовил: Аверко Денис Сергеевич @Nymexis г. Омск (специалист по ЗИ)

Комментарии

Загрузка...
Если комментарии не загружаются, можете попробовать отключить блокировщик рекламы для этого сайта