用于迭代列表中步骤的 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/3
和 2n
之间存在差异,它仍然只是 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&Runing Time,如何将其转换为迭代算法