python list remove复杂度_python3 list时间复杂度

作者在做力扣算法题时因算法时间复杂度过高超出时间限制,进而了解Python列表操作复杂度。介绍了数组和时间复杂度概念,分析了列表特点,给出常见列表操作的时间复杂度,指出列表适合访问索引元素、尾部增减元素,还简单提及空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、引题

本周在做力扣上的算法题(删除排序数组中的重复项)时,遇到了超出时间限制的问题,后来才知道是我设计的算法时间复杂度过高,于是我就对list的各个基本操作和常用函数的复杂度作了个了解。

二、背景知识

1.数组是一种线性表结构,其用一块连续的内存空间,来存储一组具有相同类型的数据

2.时间复杂度,也叫做渐进时间复杂度,通常用大O公式书写,表示代码的执行时间随数据规模增长的变化趋势,而非真正的执行时间。因此大O关注的是变化趋势。

三、列表(list)特点

1.底层基于数组实现

python list本质上是一个over-allocate的数组,啥叫over-allocate呢?就是当底层数组容量满了而需要扩充的时候,python依据规则会扩充多个位置出来。比如初始化列表array=[1, 2, 3, 4],向其中添加元素23,此时array对应的底层数组,扩充后的容量不是5,而是8。这就是over-allocate的意义,即扩充容量的时候会多分配一些存储空间。这样做的优点当然是提高了执行效率,否则每次添加元素,都要对底层数组进行扩充,效率是很低下的。另外,当列表存储的元素在变少时,python也会及时收缩底层的数组,避免造成内存浪费。这里可以通过对列表的实践,验证扩充与收缩的过程(通过 sizeof()或sys.getsizeof()查看内存变化,并推算容量值)。

2.属于引用数组

>>> a = [1, 2, 3, 4]

>>> a.__sizeof__()

72

>>> b = ['hello', 'world', 'mac']

>>> b.__sizeof__()

64

>>> c = [int('10'), str(8)]

>>> c.__sizeof__()

56

>>> d = 23

>>>

>>> l = []

>>> l.__sizeof__()

40

>>> l.append(a)

>>> l

[[1, 2, 3, 4]]

>>> l.__sizeof__()

72

>>> l.append(b)

>>> l.__sizeof__()

72

>>> l.append(c)

>>> l.__sizeof__()

72

>>> l.append(d)

>>> l.__sizeof__()

721

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

我们知道,初始列表的底层数组容量是0,第一次会扩充为4个元素的容量,占用32个字节,每个元素占用8个,注意这里就是每个元素占用8个字节,而不是平均的结果为8个字节。如果列表中存放实际的元素,那上面实践中列表l添加完元素列表a之后,其占用的字节就不会是72了。因此列表本质上存储的是对象的引用。

四、列表各操作时间复杂度分析

常见的时间复杂度高低排序:

O(1)

具体的看下表,'n’是容器中当前的元素数, 'k’是需要操作的元素个数。

操作

时间复杂度

index()

O(1)

append()

O(1)

extend()

O(k)

insert()

O(n)

count()

O(n)

remove()

O(n)

pop()

O(1)

pop(i)

O(n)

sort()

O(n log n)

reverse()

O(n)

len()

O(1)

max(),min()

O(n)

del(del list[i] 或者 del list[i:j])

O(n)

slice [x:y] (切片)

O(k)

iterration(列表迭代)

O(n)

in 关键字

O(n)

通过分析可以发现,列表不太适合做元素的遍历、删除、插入等操作,对应的时间复杂度为O(n);访问某个索引的元素、尾部添加元素或删除元素这些操作比较适合做,对应的时间复杂度为O(1)。

其他集合内置方法的时间复杂度

最后简单了解一下空间复杂度:

空间复杂度是用来评估算法内存占用大小的方式。定义一个或多个变量,空间复杂度都是为1;列表的空间复杂度为列表的长度。

a = 'Python' #空间复杂度为1

b = 'PHP'

c = 'Java'

num = [1, 2, 3, 4, 5] #空间复杂度为5

num = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]] #空间复杂度为5*4

num = [[[1, 2], [1, 2]], [[1, 2], [1, 2]] , [[1, 2], [1, 2]]] #空间复杂度为3*2*21

2

3

4

5

6

7

Python3中,使用PyCharm创建和管理线性表可以通过内置的列表类型(list)来实现。列表是一种动态数组,能够存储任何类型的数据,并支持增删改查等多种操作。以下是如何创建和管理线性表的步骤: 参考资源链接:[数据结构期末复习:重点概念与习题解析](https://wenku.csdn.net/doc/3y24c5jqge?spm=1055.2569.3001.10343) 1. 创建一个空的线性表(列表): ```python my_list = [] ``` 2. 向线性表添加数据元素: ```python my_list.append(10) # 添加单个元素 my_list.extend([20, 30, 40]) # 添加多个元素 ``` 3. 访问线性表中的数据元素: ```python print(my_list[0]) # 访问第一个元素 print(my_list[-1]) # 访问最后一个元素 ``` 4. 修改线性表中的数据元素: ```python my_list[1] = 25 # 将第二个元素修改为25 ``` 5. 删除线性表中的数据元素: ```python del my_list[1] # 删除第二个元素 my_list.remove(30) # 删除值为30的元素 ``` 线性表的操作时间复杂度分析如下: - 访问元素的操作(如`my_list[i]`)时间复杂度为O(1),因为列表的元素是连续存储的。 - 插入或删除操作的时间复杂度取决于位置: - 如果在列表末尾插入或删除,时间复杂度为O(1)。 - 如果在列表开头插入或删除,时间复杂度为O(n),因为需要移动其他所有元素。 - 如果在列表中间插入或删除,最坏情况下的时间复杂度也为O(n),因为可能需要移动插入点之后的所有元素。 为了深入理解和掌握数据结构的概念,尤其是线性表的存储结构、操作和时间复杂度分析,我推荐你查阅《数据结构期末复习:重点概念与习题解析》这一资料。该资料不仅涵盖了线性表的相关知识,还包括了其他数据结构的基础概念和习题,能够帮助你在理论和实践中都有所提高。 参考资源链接:[数据结构期末复习:重点概念与习题解析](https://wenku.csdn.net/doc/3y24c5jqge?spm=1055.2569.3001.10343)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值