Какой из них вы предпочитаете создавать списки в Python? Вы будете удивлены, узнав, что они не работают точно так же.

Прежде всего, мы сравним производительность создания списка с использованием скобок напрямую и с использованием конструктора list().

Давайте сравним время создания пустого списка. Мы используем волшебную команду %timeit , она выполняет оператор настройки один раз, а затем возвращает время, необходимое для выполнения основного оператора несколько раз, измеряемое в секундах как число с плавающей запятой. Аргумент — это количество проходов цикла, по умолчанию равное одному миллиону.

Чтобы создать пустой список, [] работает более чем в три раза быстрее, чем list(), а если я создаю список с каким-то содержанием?

Потому что []это буквенный синтаксис. Python может создать байт-код только для создания списка. Мы будем использовать модуль dis. Он поддерживает анализ байт-кода CPython путем его дизассемблирования.

Как мы можем видеть на картинке выше, имя list() является отдельной переменной и должно быть разрешено, стек должен быть задействован для передачи аргументов, фрейм должен быть сохранен для последующего извлечения, а вызов должен быть быть сделано. Это все требует больше времени.

Для пустого случая это означает, что у вас есть как минимум LOAD_NAME (который должен искать в глобальном пространстве имен, а также builtins модуль), за которым следует CALL_FUNCTION, который должен сохранить текущий кадр.

Случай с числовым содержанием дизассемблера очень похож:

Мы видим, что байт-коды двух методов совершенно разные. Это должно быть причиной того, что производительность отличается.

Когда мы используем [], байт-код показывает, что есть только два шага.

  1. BUILD_LIST — Создайте список Python
  2. RETURN_VALUE — Возвращает значение

Очень просто, правда? Когда интерпретатор Python видит выражение [], он просто знает, что ему нужно построить список. Итак, это очень прямолинейно.

Как насчет list()?

  1. LOAD_NAME — Попробуйте найти объект «список» во всех переменных области видимости.
  2. CALL_FUNCTION — Вызвать функцию «list» для создания списка Python.
  3. RETURN_VALUE — Возвращает значение

Каждый раз, когда мы используем что-то с именем, интерпретатор Python будет искать имя в существующих областях видимости переменных. Он выполняет поиск в таком порядке, как Локальная область действия -> Включающая область действия -> Глобальная область действия -> Встроенная область действия.

Этот поиск определенно потребует некоторого времени.

То же самое происходит, когда вы используете конструкцию dict() вместо {} (пустой dict). Некоторые люди говорят, что [] и {} являются наиболее пифоническими и удобочитаемыми способами создания пустых списков/слов. Однако будьте осторожны при использовании {} для создания словаря с содержимым:

this_is_a_set = {5}
this_is_a_dict = {}

Первый создает набор с одним элементом, второй создает пустой словарь и не набор.

Теперь ты знаешь. Предпочитайте использовать [] вместо list() в вашем коде.

Для контента на португальском языке @aprendadatascience или https://aprendadatascience.com

Использованная литература:

https://docs.python.org/3/library/timeit.html