Я хочу перебрать каждый третий элемент в моем списке. Но если подумать о нотации Big-O, будет ли сложность Big-O O (n), где n - количество элементов в списке, или O (n / 3) для каждого третьего элемента?

Другими словами, даже если я укажу, что список должен повторяться только по каждому третьему элементу, Python все еще выполняет цикл по всему списку?

Пример кода:

def function(lst):
    #iterating over every third list
    for i in lst[2::3]:
        pass

0
yama 28 Ноя 2021 в 03:16
1
Это будет O (n / 3). Нотация Big-O отделена от физической реализации, поэтому не имеет значения, как Python реализует ее, если она есть. При этом python смотрит только на каждый третий элемент и полностью игнорирует остальные.
 – 
Locke
28 Ноя 2021 в 03:18
6
Лучший вопрос: есть ли разница между O(n) и O(n/3)?
 – 
Silvio Mayolo
28 Ноя 2021 в 03:20
Было бы проще думать об этом как о доступе только к каждому третьему индексу в пределах длины списка, а не в контексте структуры данных, содержащей эти элементы.
 – 
Locke
28 Ноя 2021 в 03:24
Почему? Никакие индексы не задействованы, и ваше предложение не меняет количество повторяемых «вещей», как бы вы их ни называли.
 – 
chepner
28 Ноя 2021 в 03:25
1
Создает ли он новый список или нет, не имеет значения. Это O (n); в двух крайних случаях это разница между n/3 и 2n, которая по-прежнему является постоянным множителем 6: в любом случае это O (n).
 – 
chepner
28 Ноя 2021 в 03:39

2 ответа

Лучший ответ

При использовании нотации Big-O мы игнорируем любые скалярные кратные перед функциями. Это потому, что алгоритм все еще требует «линейного времени». Мы делаем это, потому что нотация Big-O учитывает поведение алгоритма при масштабировании до больших входных данных.

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

Математически мы можем сказать это из-за термина M в определении (https://en.wikipedia.org/ wiki / Big_O_notation):

abs(f(x)) <= M * O(f(x))

2
codesflow 28 Ноя 2021 в 03:28

Обозначение Big O останется здесь O (n).

Обратите внимание на следующее:

n = some big number
for i in range(n):
  print(i)
  print(i)
  print(i)

Считается ли выполнение 3 действий O (3n) или O (n)? На). Снижается ли реальная производительность при выполнении трех действий вместо одного? Абсолютно!

Обозначение Big O учитывает скорость роста функции, а не физическое время выполнения.

Рассмотрим следующее из библиотеки pandas:

# simple iteration O(n)
df = DataFrame([{a:4},{a:3},{a:2},{a:1}])
for row in df:
  print(row["a"])
# iterrows iteration O(n)
for idx, row in df.iterrows():
  print(row["a"])
# apply/lambda iteration O(n)
df.apply(lambda x: print(x["row"])

Все эти реализации можно рассматривать как O (n) (константа отбрасывается), однако это не обязательно означает, что время выполнения будет таким же. Фактически, метод 3 должен быть примерно в 800 раз быстрее, чем метод 1 (https://towardsdatascience.com/how-to-make-your-pandas-loop-71-803-times-faster-805030df4f06)!

Другой ответ, который может вам помочь: Почему константа всегда выпал из анализа большого количества?

0
bguest 28 Ноя 2021 в 03:31