Функция Python all () настолько мощна, что была объявлена ​​частью встроенной библиотеки. Понимание того, как использовать эту условную функцию цепочки, может сделать ваш код более лаконичным, гибким и * питоническим * для загрузки!

Функция Python all() - это встроенная функция, которая оценивает правдивость всей коллекции. Его можно использовать в статическом синтаксисе или более динамических реализациях, включая такие функции, как понимание списков и генераторы. Его можно использовать в сочетании с другими языковыми функциями для создания мощных и сжатых условных операторов.

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

TL; DR - функция all() проверяет всю коллекцию на наличие условий, оцениваемых как True

# Have a collection of integers
>>> nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Check all items are integers
>>> all(int(x) for x in nums)
# That's a bingo
True

Основное использование

Функция Python all используется для проверки всех членов коллекции на правдивость. В Python есть много повторяемых типов, включая списки, словари, наборы, генераторы и даже строки. Каждый из этих типов данных можно использовать вместе с функцией all. Его можно сравнить с более семантическим для всех в списке, проверьте, что каждый имеет значение True. Рассмотрим несколько канонических вариантов использования.

Случай 1: базовая проверка правды

# Create a list
l = [0, 1, 2, 3, 4, 5]
all(l)
>>> False

Этот пример демонстрирует основное поведение функции all: тестирование всех элементов в итерации на наличие значения True или False. В этом случае отказавший элемент является первым элементом; 0 (эквивалент False). Например:

# Check the numerical value of False
>>> 0 == False
True
# Check the numerical value of True
>>> 1 == True
True
# Check for other values of True
>>> 1 == True and 2 == True and 3 == True and 4 == True and 5 == True
False
# Remove the 0 element from list, use all
>>> all([1, 2, 3, 4, 5)]
True
# Check an empty list
>>> all([])
True

Эти примеры могут показаться слегка раздражающими. Это сладкое чувство познания чего-то нового! Согласно официальной документации Python функция all будет; Вернуть True, если все элементы итерации истинны (или если итерация пуста). Я нахожу это утверждение запутанным и перефразирую его следующим образом:

Возвращает True, если все элементы итерации не равны False. Утверждения x is not False и x is True логически эквивалентны, но первый предлагает лучшую ясность в этом контексте.

Имея это в виду, давайте еще раз рассмотрим первый пример и то, почему он дал результат False с помощью функции all.

# Create a list l = [0, 1, 2, 3, 4, 5]
>>> all(l)
False
# Create another list 
l_2 = [1, 2, 3, 4, 5]
>>> all(l_2)
True

Элемент 0 первого списка приводит к тому, что оператор all оценивает значение False. Это потому, что числовое значение 0 эквивалентно скрытому False. Прочтите эту статью, чтобы узнать больше о том, как Python (и другие языки программирования) представляют числа внутри себя. При удалении 0 остаются только ненулевые элементы, которые оцениваются как not-False.

Полнота любой логической функции всегда трудна для понимания. Эти примеры предназначены для лучшей иллюстрации нюансов функции all, чтобы можно было лучше понять следующие, более сложные случаи.

Другие примеры

Я считаю, что большинство приложений, в которых я использую функцию all, в некоторой степени динамичны. В большинстве случаев я использую синтаксис понимания для проверки большого количества членства в качестве условного оператора для выполнения какой-либо другой логики. Другими словами, используя сжатый синтаксис Python! Рассмотрим следующий пример:

from string import printable
# Check if all letters of a string are in the 
# string.printable variable (ASCII characters)
if all(x in printable for x in 'hello, world!'):
    print("All Letters are ASCII!")
else:
    print("Non-ASCII letters found!")
# The result:
All letters as ASCII!

В этом примере функция all() используется для проверки того, что каждая буква в строке "hello, world!" находится в переменной string.printable.

Примечание. Переменная string.printable равна следующей строке (за вычетом нескольких пробелов):

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Ознакомьтесь с таблицей ASCII для получения дополнительной информации об этих типах наборов символов. В этом примере демонстрируется базовый вариант использования функции all (), с которым можно столкнуться в естественных условиях. Тестирование нескольких условий членства - мощный способ принимать решения со сложными или динамическими данными. Рассмотрим более сложный пример.

Объединение заявлений

Здесь мы увидим пример, в котором функция all () используется в сочетании с другой встроенной функцией Python; функция any (). Используя очень надуманный набор данных, мы проверим, присутствует ли одно из значений цвета во всех ключевых значениях записей данных:

# Define a set of values
colors = ['red', 'blue', 'green']
numbers = [1, 2, 3]
# Generate some random data
>>> data = {
    choice(colors) + "-" + choice(colors): choice(numbers) * choice(numbers)
    for x in range(10)
}
{'blue-blue': 3, 'blue-red': 2, 'red-blue': 2, 'green-green': 6, 'red-green': 1, 'blue-green': 2}
# Check that ALL members in 'data' contain ANY member of 'colors'
>>> all(any(x in y for y in data.keys()) for x in colors)
True

Это демонстрирует не только то, как функцию all() можно использовать динамически, но и радость использования операторов понимания Python. Приносим извинения за причудливую конструкцию объекта data - у меня не хватило воображения!

Извлечение предметов в другую коллекцию

Метод Python’s all() может использоваться для извлечения подмножеств из коллекций, где требуется условное членство. Рассмотрим следующий [очень надуманный] пример:

# Create some random collection of numbers
num_pairs = [(1, 3), (2, 4), (3, 6, 9), (1, 2, 3, 4), (4, 6, 8)]
# Extract any pair of numbers where only even numbers are present
evens = [x for x in num_pairs if all(n % 2 == 0 for n in x)]
>>> evens
 
# Results in sub-sets containing
# only all-even values
[(2, 4), (4, 6, 8)]

Это демонстрирует использование функции all() для проверки каждого кортежа в коллекции только на четные значения. Для любого кортежа, не содержащего нечетных значений (odd == not False), синтаксис понимания Python соберет этот элемент в новую коллекцию evens.

Дополнительные соображения

При тестировании больших коллекций на членство могут возникнуть некоторые проблемы с производительностью. В следующем примере я воспользуюсь функцией all(), чтобы проверить список из 100 000 000 миллионов случайно сгенерированных единиц и нулей, чтобы убедиться, что все элементы являются целочисленными значениями. Однако перед проверкой я добавлю один нецелочисленный символ 'z' в конец коллекции.

# Create a list 100MMK 1's or 0's, chosen randomly
import random
nums = list(random.choice([0, 1]) for x in range(10**8))
# Add the letter "z" to the end
nums.append('z')
# Test that all members are numerical
import timeit
>>> timeit.timeit(lambda: all(type(x) == int for x in nums))
# Total Execution Time
5.397376900000005

Этот код делает следующее:

  1. Создает список из 100 000 000 единиц 1 и 0 в случайном порядке.
  2. Добавить один символ 'z' в конец
  3. Убедитесь, что все элементы в списке являются целочисленными значениями

Обратите внимание, что общее время выполнения этого кода составляет ~ 5,40 секунды с символом «z» в конце последовательности. Это время отражает необходимость all() функций перебирать каждый отдельный элемент, прежде чем можно будет убедиться, что все они являются целыми числами.

Теперь представьте, что символ 'z' был помещен в начало. Без надлежащих проверок можно обнаружить, что перебирают всю коллекцию, прежде чем определять истинность. Например, подсчет общего количества вхождений нецелочисленного элемента и сравнение его с 0.

Разработчики Python умны. В тот момент, когда условие оценивается как значение, отличное от истинного, функция all() выполняет короткое замыкание, а не выполняет полную оценку. Рассмотрим приведенный выше пример, на этот раз с символом 'z' , добавленным в начало коллекции.

# Create a list 100MM 1's or 0's, chosen randomly
import random
nums = list(random.choice([0, 1]) for x in range(10**8))
# Add the letter "z" to the start
nums.insert(0, 'z')
# Test that all members are numerical
import timeit
timeit.timeit(lambda: all(type(x) == int for x in nums), number=1)
# A reeaaly small value
2.600000001962144e-06

Вам нужно это знать, чтобы пользоваться функцией all()? Точно нет. Я считаю, что лучшее понимание того, как разрабатывались функции, особенно рассмотрение вопросов производительности, помогает прояснить их применение. Я такой ботаник.

Последние мысли

На мой взгляд, функция Python all() - один из самых полезных инструментов языка. По моему опыту, его способность проверять правдивость на практике бывает полезна каждый день. Другие языки и лямбда-выражения нашли свое место в аналогичной утилите, но немногие из них предлагают готовый, производительный, собственный синтаксис, который делает Python. В сочетании с генераторами, пониманием и небольшим количеством воображения - функция all() может заставить чувствовать себя действительно умным (во всяком случае, до времени проверки кода!)

Статья Python’s all (): встроенная функция для поиска среди множества была впервые опубликована на веб-сайте alpharithms и переиздана здесь с разрешения.