len()函数的成本


Answers:


340

它的O(1) (固定时间,不依赖于要素的实际长度-非常快)对你所提到的每一种类型,再加上set其他如array.array


17
感谢您的帮助!是否存在不是本机类型的情况?
mvanveen


84

所有这些对象都保持其自身长度。提取长度的时间很小(大O表示形式为O(1)),并且主要由[粗略描述,用Python术语而不是C术语编写]:在字典中查找“ len”并将其分派给built_in len函数,它将查找对象的__len__方法并调用...所有要做的就是return self.length


3
我认为这是最合适的答案,因为它可以深入了解实施细节。
AK

为什么没有length显示在词典中dir(list)
ViFI

这就是我想要的
Visakh Vijayan

@ViFI,因为这只是一个示例。图示的list.lenght变量是用C实现的,而不是Python。
科瓦尔斯基

73

以下测量提供了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

元组:

$ 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

串:

$ 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

字典(dictionary-comprehension在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

数组:

$ 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

集合(集合理解在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

双端队列:

$ 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

1
尽管它显示了我们已经知道的知识,但它并不是一个很好的基准。这是因为range(10)和range(1000000)不应为O(1)。
未知

3
到目前为止,这是最好的答案。您应该添加一个结论,以防万一有人没有意识到固定的时间。
santiagobasulto

4
感谢您的评论。我添加了关于的O(1)复杂度的注释len(),并修复了测量值以正确使用该-s标志。
Mechanical_meat

重要的是要注意,将长度保存到变量中可以节省大量的计算时间: python -m timeit -s "l = range(10000);" "len(l); len(l); len(l)"每个循环223 ns,每个循环python -m timeit -s "l = range(100);" "len(l)"66.2 ns
Radostin Stoyanov

16

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


3

我一直在考虑Python中的len()取决于列表的大小,因此如果多次使用,我总是将长度存储在变量中。但是今天在调试时,我注意到列表对象中的__len__属性,因此len()必须只是在获取它,这使得复杂度为O(1)。所以我只是用谷歌搜索是否有人已经问过这个帖子。


但这__len__是一个功能,而不是代表列表长度的变量。
科瓦尔斯基

@Kowalski是的len是一个函数,但它所做的只是返回了self.length
AYUSH SENAPATI

但是您的帖子对此没有任何说明。您又怎么知道该list.__len__函数在恒定时间内运行?它可以,但不仅仅是因为它是一个函数。因为它是那样实现的。
科瓦尔斯基
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.