1、这里主要讨论python两种数据类型上各种操作的大O数量级:列表和字典

主要通过运行试验来估计其各种操作运行时间数量级

2、比较list和dict的操作

python dict 内存上线 python dict性能_算法

  • 列表的各种操作的实现方法有很多(比如append,可以有多种实现方法),那么具体的,是如何选择哪种实现方法呢?
  • 起始总的方案就是,让最常用的操作性能最好,牺牲不太常用的操作。

80/20准则:80%的功能其使用率只有20%。(简单来说,就是保证那些常用的骚操作性能好一点,不太常用的操作可以性能弱一点

python dict 内存上线 python dict性能_执行时间_02

3、List列表数据类型的常用操作类型

  • 最常用的是:索引,包括取值和赋值,如v = a[i], a[i] = v
  • 列表增长:可以选择append()和__add__()、+

lst.append(v)执行时间是O(1)

lst = lst + [v]执行时间复杂度是O(n+k),k是被加的列表长度

选择哪个方法来操作列表,决定了程序的性能

 

实验:

  • 4 种生成前n个整数列表的方法:
# 1、首先是循环连接列表(+)方式生成
def test1():
    l = []
    for i in range(1000):
        l = l + [i]

# 2、用append方法添加元素生成
def test2():
    l = []
    for i in range(1000):
        l.append(i)

# 3、用列表推导式生成
def test3():
    l = [i for i in range(1000)]


# 4、用range函数生成
def test4():
    l = list(range(1000))

然后使用timeit模块对函数计时

创建一个 Timer 对象 , 指定需要 反复运行 的 语句和只需要 运行一次 的 “ 安装语句“,然后调用这个对象的 timeit 方法 , 其中可以 指定反复运行多少次

python dict 内存上线 python dict性能_python_03

运行结果:

python dict 内存上线 python dict性能_数据结构_04

可以看到,4 种方法运行时间差别很大:

列表连接最慢,list range最快,最多相差进200倍。

append也比列表连接快得多,列表推导式的速度是append的两倍左右。

4、list列表基本操作的大O数量级

python dict 内存上线 python dict性能_python_05

  • 观察上图可以发现,对pop这个操作:

pop()从列表末尾移除元素,O(1)

pop(i)从列表中间删除元素,O(n)  ----->补充说明:实际上不一定是n,也可能是n/2等,但是数量级都是n 

原因在于python选择的实现方法:从中部移除元素的话,要把移除元素后面的元素全部向前挪位复制一遍,这个看起来比较麻烦,但是这种实现方法能够保证按索引取值和赋值的操作很快,达到O(1),是对常用和不常用操作的折中方案

python对列表的大O数量级:

range < 列表推导式 < append < +

  • list.pop()的计时实验

通过改变列表的长度来测试两个操作的增长趋势

python dict 内存上线 python dict性能_数据结构_06

 

python dict 内存上线 python dict性能_算法_07

 

将实验数据化成图表,可以看出增长趋势

pop()是常数,pop(0)是线性增长

python dict 内存上线 python dict性能_python_08

 

5、dict字典数据类型

  • 字典与列表不同 , 根据关键码 ( key ) 找到数据项 , 而列表是根据位置 ( index )

python dict 内存上线 python dict性能_算法_09

  • 设计一个性能试验来验证list种检索一个值,以及字典中检索一个值(get函数)的时间对比

python dict 内存上线 python dict性能_数据结构_10

运行结果:

python dict 内存上线 python dict性能_数据结构_11

  • 可见,字典的执行时间与字典的规模无关,是常数
  • 列表的执行时间随着列表规模增大而线性上升

大多数情况下,dict比list更高效

6、pythong官方的算法复杂度网站:https://wiki.python.org/moin/TimeCompl