Рубрики
Без рубрики

Сложность операций Python

https://youtu.be/smutqeap1w8 В этом руководстве вы узнаете сложность выполнения разных операций Python. Затем вы узнаете, как рассчитать сложность вашей собственной функции, сочетая классы сложности его составляющих. Это называется «статический анализ», учебное пособие на основе (источника), но он значительно расширяет его с более практическими примерами, интерактивными … Сложность операций Python Reading »

Автор оригинала: Chris.

В этом руководстве вы узнаете сложность выполнения разных операций Python.

Затем вы узнаете, как рассчитать сложность вашей собственной функции, сочетая классы сложности его составляющих. Это называется «Статический анализ»

Учебник слабо основан на ( источник ) Но это значительно расширяет его с более практическими примерами, интерактивными фрагментами и пояснительным материалом.

Представляем Big-O

Определение : Сложность операции (или алгоритма для этого вещества) – количество ресурсов, необходимых для его запуска ( Источник ). Ресурсы могут быть время ( сложность времени выполнения ) или пространство ( сложность памяти ).

Итак, как вы можете измерить сложность алгоритма? В большинстве случаев сложность алгоритма не стата. Это зависит от размера входа к алгоритму или операции.

Например, список методов списка .sort () имеет один входной аргумент: объект списка для сортировки. Сложность выполнения не является постоянной, он увеличивается с увеличением размера списка. Если есть больше элементов, которые будут отсортированы, время выполнения алгоритма увеличивается.

Функция сложности

Данный размер ввода N , вы можете описать сложность вашего алгоритма с функцией ввода N F ( n ) Это определяет количество «единиц ресурсов» (например, время, память), необходимое для завершения его (в худшем случае или средний случай).

Скажи, у вас есть три реализации в Сортировать список : Реализация_1 , Реализация_2 , Реализация_3 Отказ

На рисунке показаны три функции сложности. Ось X измеряет размер ввода (в нашем примере, это будет размер списка). Ось Y измеряет сложность в отношении этого ввода.

  • Реализация_1 имеет квадратичную функцию сложности f (n) .
  • Реализация_2 имеет квадратичную функцию сложности f (n) .
  • Реализация_3 имеет функцию логарифмической сложности f (n) log (n) Отказ

Вы можете увидеть код, который мы использовали для создания этого сюжета здесь:

import matplotlib.pyplot as plt
import math

implementation_1 = [n**2 for n in range(1, 100, 10)]
implementation_2 = [2*n**2 for n in range(1, 100, 10)]
implementation_3 = [n*math.log(n) for n in range(1, 100, 10)]

plt.plot(implementation_1, '--.', label='implementation 1')
plt.plot(implementation_2, '-o', label='implementation 2')
plt.plot(implementation_3, '-x', label='implementation 3')

plt.legend()
plt.xlabel('Input (ex: List Size)')
plt.ylabel('Complexity (ex: Runtime)')
plt.grid()
plt.show()

Конечно, приятно тратить как можно меньше ресурсов, поэтому функция логарифмической сложности превосходит квадратичные функции сложности.

Обозначение Big-O

Для больших входов поведение времени выполнения будет доминировать со стороны функции сложности, которая растет быстрее всего. Например, квадратичная функция сложности времени выполнения f (n) + 100000n + 999 будет намного лучше, чем функция сложности кубических временных времен g (n) .1n³ Отказ

Почему? Потому что рано или поздно функция g (n) будет производить гораздо более высокие значения, чем f (n) как размер ввода n увеличивается.

На самом деле, вы можете утверждать, что единственная важная часть функции сложности является частью, которая растет быстрее всего с увеличением размера ввода.

Это именно то, что такое нотация Big-o:

Обозначение больших o характеризует функции в соответствии с их темпами роста: различные функции с одинаковыми скоростью роста могут быть представлены с использованием одинаковой записи. ( Wiki )

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

Чтобы показать это, посмотрите на наши два примера:

  • Функция сложности f (n) + 100000n + 999 Растет как O (n²) Отказ
  • Функция сложности g (n) .1n³ Растет как O (n³) Отказ

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

Примеры Big-o функций сложности

Итак, вот несколько примеров функций сложности и их асимптотический рост в нотации Big-O:

Вы можете видеть, что асимптотический рост функции (в нотации Big-O) преобладает самый быстрорастущий термин в уравнении функции.

Сложность Python

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

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

Сложность списка Python

Предположим, что длина типа данных определяется как N (Это- n (data_type) ). Теперь вы можете классифицировать асимптотическую сложность различных функций сложности следующим образом:

л [я] Показатель O (1)
O (1)
Лен (л) Длина O (1)
l.append (42) Присоединиться к O (1)
l.pop () Поп O (1)
l.clear () Прозрачный O (1)
l [A: B] Нарезка O (b-a)
l1.extend (l2) Продлевать O (Лен (L1) + ЛЕН (L2))
Список (ITER) Конструктор O (ЛЕН (ИТЕР))
Л1 Равенство На)
l [A: B] = … Наседание нарезки На)
del l [i] Удалить На)
l.remove (…) Удалять На)
х в л / х не в л Членство На)
l.copy () Скопировать На)
l.pop (0) Поп На)
мин (л) Мин На)
Макс (л) Максимум На)
l.reverse () Задний ход На)
Для х в л: Истребитель На)
l.sort () Сортировать O (n log (n))
l * k. Умножать O (n k)

Кортеры похожи друг на друга, – с несколькими исключениями: вы не можете изменить кортеж, потому что они неизменяются.

Давайте рассмотрим еще одну важную структуру данных:

Python установить сложность

Предположим, что длина типа данных определяется как N (Это- n (data_type) ). Если в одной операции есть два набора, такие как S1 длина даны переменными N1 и N2 Отказ Теперь вы можете классифицировать асимптотическую сложность различных функций сложности следующим образом:

Лен (ы) Длина O (1)
S.ADD (42) Добавлять O (1)
42 в S / 42 не в с Членство O (1)
S.Remove (42) Удалять O (1)
S.POP () Поп O (1)
S.CLEAR () Прозрачный O (1)
Set (ITER) Конструктор На)
S1 / S1. Равенство O (мин (N1, N2))
S1 |. S2. Союз O (N1 + N2)
S1 & S2. Пересечение O (мин (N1, N2))
S1 – S2. Разница O (n2)
S1 ^ S2. Симметричная разница O (N1)
Для х в с: Итерация На)
S.copy () Скопировать На)

Я подчеркнул заданные операции, которые более эффективны, чем соответствующие операции списка. Причина тех, которые существуют O (1), а не O (n), состоит в том, что структура данных списка также поддерживает упорядочение элементов, которые вступают в дополнительный накладные расходы.

Сложность словаря Python

Теперь взгляните на момент сложности операций словаря Python:

Dict [K] Индекс (получить) O (1)
O (1)
Лен (Dict) Длина O (1)
del dict [ключ] Удалить O (1)
Dict.pop (k) Поп O (1)
Dict.clear () Прозрачный O (1)
Dict.keys () Ключи O (1)
Dict (…) Строительство На)
Для K в Dict: Итерация На)

Большинство операций являются O (1), потому что словари Python разделяют несколько свойств наборов Python (например, Fast Explation Action).

Составление классов сложности

Теперь вы знаете сложность разных операций. Но как вы получаете сложность вашего алгоритма?

Концепция проста: вы нарушаете большую проблему ( Зная сложность всего алгоритма ) в ряд меньших проблем ( Зная сложность индивидуальных операций ).

Затем вы реком укрепите сложности индивидуальной операции, чтобы получить решение большой проблемы.

Как? Начнем с небольшого примера: вы сначала получите список из словаря значений списка. Затем вы сортируете список:

d = {1: [3, 1, 2, 4],
     2: [4, 4, 1, 9]}

lst = d.get(1)
lst.sort()
print(lst)
# [1, 2, 3, 4]

Попробуйте сами в нашем интерактивном коде Shell (нажмите «Запустить», чтобы выполнить код):

У вас есть четыре операции в фрагменте кода. Давайте аннотируем каждую операцию с классом сложности.

# Operation 1: Dictionary Creation --> O(n)
d = {1: [3, 1, 2, 4],
     2: [4, 4, 1, 9]}

# Operation 2: Dictionary Get --> O(1)
lst = d.get(1)

# Operation 3: List Sorting --> O(n log n)
lst.sort()

# Operation 4: Print List --> O(n)
print(lst)

Знание классов сложности различных операций, вы можете рекомбинировать его следующим образом:

O(n) + O(1) + O(n log n) + O(n)
(1) = O(n + 1 + n log n + n)
(2) = O(n log n + 2n + 1)
(3) = O(n log n)

Вы видите в уравнении (1) что вы могли бы назвать «Цепное правило сложности анализа» : O (f (n)) + (f (n) + g (n)) .

Вы можете увидеть в уравнении (3) что нотация Big-O сосредоточено только на самом большом растущем сроке. В нашем случае O (n log n) растет быстрее, чем O (2n) .

Вот два важных примера рекомбинации Big-O:

  • O (f (n)) + (f (n) + (2f (n)) (f (n) . Другими словами, выполняя операцию постоянного (фиксированного) количество раз, не изменяет общую сложность алгоритма.
  • O (f (n) + (f (n)) Если функция сложности f (n) растет быстрее, чем g (n) Отказ Пример – O (n³ + (n³) .

В программировании вы также можете иметь Условное исполнение :

if condition:
   f(n)
else:
   g(n)

Вы можете рекомбинировать класс сложности общего фрагмента кода следующим образом: O (max (f (n), g (n)) . Грубо говоря, (если условие может быть правдой), сложность условного исполнения является максимум обоих блоков f (n) или g (n) .

Пример :

if lst:
   lst.sort()
else:
   lst = [1, 2, 3, 4]

Сложность – это O (n log n) потому что он растет быстрее, чем На) – сложность блока в остальное заявление Отказ

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

Если вы повторите функцию f (n) м Времена, вычислительная сложность – m * (m f (n)) . Если м является постоянным, вычислительная сложность упрощает O (f (n)) .

Куда пойти отсюда?

Достаточно теории, давайте познакомимся!

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

Практические проекты – это то, как вы обостряете вашу пилу в кодировке!

Вы хотите стать мастером кода, сосредоточившись на практических кодовых проектах, которые фактически зарабатывают вам деньги и решают проблемы для людей?

Затем станьте питоном независимым разработчиком! Это лучший способ приближения к задаче улучшения ваших навыков Python – даже если вы являетесь полным новичком.

Присоединяйтесь к моему бесплатным вебинаре «Как создать свой навык высокого дохода Python» и посмотреть, как я вырос на моем кодированном бизнесе в Интернете и как вы можете, слишком от комфорта вашего собственного дома.

Присоединяйтесь к свободному вебинару сейчас!

Работая в качестве исследователя в распределенных системах, доктор Кристиан Майер нашел свою любовь к учению студентов компьютерных наук.

Чтобы помочь студентам достичь более высоких уровней успеха Python, он основал сайт программирования образования Finxter.com Отказ Он автор популярной книги программирования Python одноклассники (Nostarch 2020), Coauthor of Кофе-брейк Python Серия самооставленных книг, энтузиаста компьютерных наук, Фрилансера и владелец одного из лучших 10 крупнейших Питон блоги по всему миру.

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

Оригинал: “https://blog.finxter.com/complexity-of-python-operations/”