Python高性能计算之列表

  接下里的系列文章中,我们将讲一下Python高性能计算,如何提高Python的计算性能?有哪些好用的库?请持续关注我们。第一节我们先来讲列表。

  Python列表是有序的元素集合,在Python中是使用大小可调整的数组实现的。数组是一种基本的数据结构,由一系列连续的内存单元组成,其中每个内存单元都包含指向一个Python对象的引用。

  列表在访问、修改和增加元素方面,速度都非常快。其中访问和修改元素,都需要从底层数组的相应位置获取对象引用,因此其复杂度是O(1)。增加元素的话,跟C++中的Vector原理类似(C++ vector用法详解),当创建一个空列表时,将分配一个长度固定的数组;当在列表末尾插入元素时,复杂度为O(1),数组中的位置逐渐被填满。当所有位置都被占据后,列表需要增大其底层数组的长度,进而触发内存的重新分配,这需要的时间为O(N)。但内存分配的操作并不频繁,因此在列表尾部增加元素的时间复杂度接近于O(1).

  在列表开头或中间增加或删除元素的效率就要慢很多了,这也很容易理解,后续所有的元素都要移动一个位置,所以时间复杂度是O(N)。因此,列表的几个常规操作的时间复杂度如下:

操作时间复杂度
list.pop()O(1)
list.pop(0)O(N)
list.append(1)O(1)
list.assert(0, 1)O(N)

  在某些场景下,我们需要频繁的对列表的头和尾进行操作,这时我们就可以使用双端队列collections.deque,这种数据结构被设计成能够在集合两端高效地增加和删除元素,在Python中,双端队列是以双向链表的方式实现的。deque的常用操作如下:

image-20201115151353509

IPython中的示例代码如下:

from collections import deque
d = deque(range(10))
>>> deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
d.pop()
>>> 9
d.popleft()
>>> 0
d
>>> deque([1, 2, 3, 4, 5, 6, 7, 8])
d.rotate(2)
>>> deque([7, 8, 1, 2, 3, 4, 5, 6])

deque操作头和尾的时间复杂度都是O(1).

操作时间复杂度
deque.pop()O(1)
deque.popleft()O(1)
deque.append()O(1)
deque.appendleft()O(1)

  虽然deque操作头和尾的时间复杂度都是O(1),由于list,但我们平时却不太会使用双端队列。主要是因为除了头和尾,访问双端队列中间的元素所需的时间为O(N)。

list和deque访问时间复杂度
list[0]O(1)
list[N/2]O(1)
list[N-1]O(1)
deque[0]O(1)
deque[N/2]O(N)
deque[N-1]O(1)

  列表查找元素通常是一种O(N)操作,使用list.index()来完成。为了提高列表的查找速度,一种简单的办法是确保底层数组是有序的,并使用模块bisect来执行二分查找。

import bisect
lst = [10, 11, 13, 14]
bisect.bisect(lst, 12)
>>> 2
bisect.bisect(lst, 13)
>>> 3

可以看到,使用bisect可以直接得出这个值应该插在什么位置,如果该值(13)本来就在列表中,默认返回的位置是列表中该元素后面的位置(3)。当然我们可以使用bisect_left函数,这样可以返回该元素前面的位置。

bisect.bisect_left(lst, 13)
>>> 2
bisect.bisect_right(lst, 13)
>>> 3

  bisect是使用二分法查找,时间复杂度是O(log(N)),在数据量较大时,比list.index()的O(N)复杂度要节省出不少的时间。

系列文章:
1. Python高性能计算之列表
2. Python高性能计算之字典
3. Python高性能计算之堆
4. Python高性能计算之字典树
5. Python常用操作的复杂度

微信公众号:Quant_Times
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值