【发布时间】:2010-11-10 01:28:24
【问题描述】:
Python 内置函数的len() 函数的成本是多少? (列表/元组/字符串/字典)
【问题讨论】:
标签: python algorithm collections complexity-theory
Python 内置函数的len() 函数的成本是多少? (列表/元组/字符串/字典)
【问题讨论】:
标签: python algorithm collections complexity-theory
您提到的每种类型都是 O(1)(恒定时间,不取决于元素的实际长度 - 非常快),加上 set 和其他类型,例如 array.array .
【讨论】:
在CPython 中对这些数据类型调用 len() 是 O(1),这是 Python 语言最常见的实现。这是一个表格的链接,该表格提供了 CPython 中许多不同函数的算法复杂性:
【讨论】:
所有这些对象都会记录自己的长度。提取长度的时间很短(大 O 表示法中的 O(1))并且主要由 [粗略描述,用 Python 术语而不是 C 术语编写]:在字典中查找“len”并将其发送到内置 len 函数,它将查找对象的 __len__ 方法并调用它......它所要做的就是 return self.length
【讨论】:
length 没有出现在dir(list) 的字典中?
list.lenght 变量是用 C 而非 Python 实现的。
以下测量结果证明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
$ 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
$ 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
【讨论】:
len() 的 O(1) 复杂性的注释,并修复了测量以正确使用 -s 标志。
python -m timeit -s "l = range(10000);" "len(l); len(l); len(l)" 223 nsec 每循环 python -m timeit -s "l = range(100);" "len(l)" 66.2 nsec 每循环
len 是 O(1),因为在您的 RAM 中,列表存储为表(一系列连续地址)。要知道表何时停止计算机需要两件事:长度和起点。这就是为什么 len() 是一个 O(1) 的原因,计算机存储了这个值,所以它只需要查找它。
【讨论】: