len()函数的成本

Imr*_*ran 261 python algorithm collections complexity-theory

len()Python内置函数的功能成本是多少?(列表/元组/串/字典)

Ale*_*lli 304

它是O(1)(恒定时间,不依赖于元素的实际长度 - 非常快)在你提到的每种类型,以及set其他类型如array.array.

  • 谢谢你的回答!是否有任何原生类型,但事实并非如此? (16认同)
  • 有趣的是,获取长度运行时仅在此处列出 - https://wiki.python.org/moin/TimeComplexity [未提及其他类型] (2认同)
  • len() 是一个非常频繁的操作,从实现的角度来看,使其 O(1) 非常容易——Python 只是将每个集合的“项数”(长度)作为集合数据结构的一部分进行存储和更新。 (2认同)

Jam*_*son 135

在这些数据类型上调用len()是CPython中的 O(1),这是Python语言最常见的实现.这是一个表的链接,它提供了CPython中许多不同函数的算法复杂性:

TimeComplexity Python Wiki页面


Joh*_*hin 73

所有这些对象都跟踪自己的长度.提取长度的时间很短(大O符号中的O(1))并且主要由[粗略描述,用Python术语编写,而不是C术语]组成:在字典中查找"len"并将其发送到built_in len函数,它将查找对象的__len__方法并调用它......所有它必须做的就是return self.length

  • 我认为这是最合适的答案,因为它可以深入了解实施细节。 (2认同)

ber*_*nie 69

以下测量结果len()为经常使用的数据结构提供了O(1)的证据.

关于timeit以下内容的注释:当使用该-s标志并且将两个字符串传递给timeit第一个字符串时,仅执行一次并且不是定时的.

列表:

$ python -m timeit -s "l = range(10);" "len(l)"
10000000 loops, best of 3: 0.0677 usec per loop

$ python -m timeit -s "l = range(1000000);" "len(l)"
10000000 loops, best of 3: 0.0688 usec per loop
Run Code Online (Sandbox Code Playgroud)

元组:

$ python -m timeit -s "t = (1,)*10;" "len(t)"
10000000 loops, best of 3: 0.0712 usec per loop

$ python -m timeit -s "t = (1,)*1000000;" "len(t)"
10000000 loops, best of 3: 0.0699 usec per loop
Run Code Online (Sandbox Code Playgroud)

串:

$ python -m timeit -s "s = '1'*10;" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop

$ python -m timeit -s "s = '1'*1000000;" "len(s)"
10000000 loops, best of 3: 0.0686 usec per loop
Run Code Online (Sandbox Code Playgroud)

字典(字典理解在2.7+中可用):

$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(10))};" "len(d)"
10000000 loops, best of 3: 0.0711 usec per loop

$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(1000000))};" "len(d)"
10000000 loops, best of 3: 0.0727 usec per loop
Run Code Online (Sandbox Code Playgroud)

阵:

$ python -mtimeit -s"import array;a=array.array('i',range(10));" "len(a)"
10000000 loops, best of 3: 0.0682 usec per loop

$ python -mtimeit -s"import array;a=array.array('i',range(1000000));" "len(a)"
10000000 loops, best of 3: 0.0753 usec per loop
Run Code Online (Sandbox Code Playgroud)

设置(设置理解在2.7+中可用):

$ python -mtimeit -s"s = {i for i in range(10)};" "len(s)"
10000000 loops, best of 3: 0.0754 usec per loop

$ python -mtimeit -s"s = {i for i in range(1000000)};" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop
Run Code Online (Sandbox Code Playgroud)

双端队列:

$ python -mtimeit -s"from collections import deque;d=deque(range(10));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop

$ python -mtimeit -s"from collections import deque;d=deque(range(1000000));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的评论.我添加了一个关于`len()`的O(1)复杂性的注释,并修复了测量以正确使用`-s`标志. (4认同)
  • 这是迄今为止最好的答案.你应该加上一个结论,万一有人没有意识到恒定的时间. (3认同)
  • 尽管它显示了我们已经知道的内容,但这并不是一个很好的基准。这是因为 range(10) 和 range(1000000) 不应该是 O(1)。 (2认同)

小智 10

len是O(1),因为在您的RAM中,列表存储为表(一系列连续地址)。要知道表何时停止,计算机需要两件事:长度和起点。这就是为什么len()是O(1)的原因,计算机会存储该值,因此只需要查找它即可。

  • @bluppfisk你完全错了。这是python文档https://docs.python.org/3/faq/design.html#how-are-lists-implemented-in-cpython (2认同)