用于迭代列表中步骤的 Big-O 表示法-Python

Posted

技术标签:

【中文标题】用于迭代列表中步骤的 Big-O 表示法-Python【英文标题】:Big-O Notation for iteration over steps in list -Python 【发布时间】:2022-01-05 10:03:05 【问题描述】:

我希望遍历列表中的每三个元素。但是在考虑 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

【问题讨论】:

这将是 O(n/3)。 Big-O 表示法与物理实现是分开的,因此 python 如何实现它并不重要,只要它。话虽如此,python 只查看每三个元素,而完全忽略其余元素。 更好的问题:O(n)O(n/3) 之间有区别吗? 可能更容易将其视为仅访问列表长度内的每三个索引,而不是在包含这些元素的数据结构的上下文中。 @Locke 为什么?不涉及任何索引,并且您的建议不会改变迭代的“事物”的数量,无论您如何称呼它们。 是否创建新列表无关紧要。这是 O(n);在两个极端情况下,n/32n 之间存在差异,它仍然只是 6 的常数因子:无论哪种方式都是 O(n)。 【参考方案1】:

此处大 O 表示法仍为 O(n)。

考虑以下几点:

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

做3个动作算O(3n)还是O(n)?在)。执行三个动作而不是一个动作会降低现实世界的性能吗?绝对!

大 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应该比方法1快800倍左右(https://towardsdatascience.com/how-to-make-your-pandas-loop-71-803-times-faster-805030df4f06)!

另一个可能对您有帮助的答案:Why is the constant always dropped from big O analysis?

【讨论】:

【参考方案2】:

使用 Big-O 表示法时,我们会忽略函数前面的任何标量倍数。这是因为该算法仍然需要“线性时间”。我们这样做是因为 Big-O 表示法会考虑算法在扩展到大输入时的行为。

意思是算法是否考虑列表中的每个元素或每隔三个元素都无关紧要,时间复杂度仍与输入大小成线性关系。例如,如果输入大小加倍,则执行时间将增加一倍,无论您查看的是每个元素还是每个第三个元素。

数学上我们可以这么说是因为定义中的 M 项 (https://en.wikipedia.org/wiki/Big_O_notation):

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

【讨论】:

以上是关于用于迭代列表中步骤的 Big-O 表示法-Python的主要内容,如果未能解决你的问题,请参考以下文章

仍然不了解 Big-O 与最坏情况时间复杂度

该算法的Big-O&Runing Time,如何将其转换为迭代算法

在树结构的 Big-O 表示法中:为啥有些来源引用 O(logN) 而有些引用 O(h)?

Big-O 表示法:加密算法

数据库索引及其 Big-O 表示法

Java Collections Framework 实现的 Big-O 总结? [关闭]