【Python】列表(list)的进阶知识


有很多操作函数的功能非常相似。例如,增加元素功能的函数有 append() 和 extend(),删除元素功能的有 clear()、 remove()、pop() 和 del 关
键字。

Python list 添加元素的方法及区别

定义两个列表(分别是 list1 和 list3),并分别使用 +、extend()、append() 对这两个 list 进行操作,其操作
的结果赋值给 l2。实例代码如下:

1. tt = 'hello'
2. #定义一个包含多个类型的 list
3. list1 = [1,4,tt,3.4,"yes",[1,2]]
4. print(list1,id(list1))
5.
6. print("1.----------------")
7.
8. #比较 list 中添加元素的几种方法的用法和区别
9. list3 = [6,7]
10. l2 = list1 + list3
11. print(l2,id(l2))
12.
13. print("2.----------------")
14.
15. l2 = list1.extend(list3)
16. print(l2,id(l2))
17. print(list1,id(list1))
18.
19. print("3.----------------")
20.
21. l2 = list1.append(list3)
22. print(l2,id(l2))
23. print(list1,id(list1))

输出结果为:

[1, 4, 'hello', 3.4, 'yes', [1, 2]] 2251638471496
1.----------------
[1, 4, 'hello', 3.4, 'yes', [1, 2], 6, 7] 2251645237064
2.----------------
None 1792287952
[1, 4, 'hello', 3.4, 'yes', [1, 2], 6, 7] 2251638471496
3.----------------
None 1792287952
[1, 4, 'hello', 3.4, 'yes', [1, 2], 6, 7, [6, 7]] 2251638471496

根据输出结果,可以分析出以下几个结论:

  1. 使用“+”号连接的列表,是将 list3 中的元素放在 list 的后面得到的 l2。并且 l2 的内存地址值与 list1 并不一
    样,这表明 l2 是一个重新生成的列表。
  2. 使用 extend 处理后得到的 l2 是 none。表明 extend 没有返回值,并不能使用链式表达式。即 extend 千万不
    能放在等式的右侧,这是编程时常犯的错误,一定要引起注意。
  3. extend 处理之后, list1 的内容与使用“+”号生成的 l2 是一样的。但 list1 的地址在操作前后并没有变化,这
    表明 extend 的处理仅仅是改变了 list1,而没有重新创建一个 list。从这个角度来看,extend 的效率要高于
    “+”号。
  4. 从 append 的结果可以看出,append 的作用是将 list3 整体当成一个元素追加到 list1 后面,这与 extend 和
    “+”号的功能完全不同,这一点也需要注意。

Python list 删除操作

接下来演示有关 del 的基本用法,实例代码如下:

1. tt = 'hello'
2. #定义一个包含多个类型的 list
3. list1 = [1,4,tt,3.4,"yes",[1,2]]
4. print(list1)
5. del list1[2:5]
6. print(list1)
7. del list1[2]
8. print(list1)

运行结果:

[1, 4, 'hello', 3.4, 'yes', [1, 2]]
[1, 4, [1, 2]]
[1, 4]

这 3 行输出分别是 list1 的原始内容、删除一部分切片内容、删除指定索引内容。可以看到,del 关键字按照指定的位置删掉了指定的内容。
需要注意的是,在使用 del 关键字时,一定要搞清楚,删除的到底是变量还是数据。例如,下面代码演示和删
除变量的方法:

1. tt = 'hello'
2. #定义一个包含多个类型的 list
3. list1 = [1,4,tt,3.4,"yes",[1,2]]
4. l2 = list1
5. print(id(l2),id(list1))
6. del list1
7. print(l2)
8. print(list1)

运行结果如下:

1765451922248 1765451922248
[1, 4, 'hello', 3.4, 'yes', [1, 2]]
Traceback (most recent call last):
File "C:\Users\mengma\Desktop\demo.py", line 8, in <module>
print(list1)
NameError: name 'list1' is not defined

第一行输出的内容是 l2 和 list1 的地址,可以看到它们是相同的,说明 l2 和 list1 之间的赋值仅仅是传递内存地址。接下来将 list1 删掉,并打印 l2,可以看到,l2 所指向的内存数据还是存在的,这表明 del 删除 list1 时仅仅是销毁了变量 list1,并没有删除指定的数据。
除了删除变量,其他的删除都是删除数据,比如将列表中数据全部清空,实现代码如下:

1. tt = 'hello'
2. #定义一个包含多个类型的 list
3. list1 = [1,4,tt,3.4,"yes",[1,2]]
4. l2 = list1
5. l3 = l2
6. del l2[:]
7. print(l2)
8. print(l3)

输出结果为:

[]
[]

可以看到,l3 和 l2 执行同样的内存地址,当 l2 被清空之后,l3 的内容也被清空了。这表明内存中的数据真正改变了。
另外,在实际过程中,即便使用 del 关键字删除了指定变量,且该变量所占用的内存再没有其他变量使用,此内存空间也不会真正地被系统回收并进行二次使用,它只是会被标记为无效内存。
如果想让系统回收这些可用的内存,需要借助 gc 库中的 collect() 函数。例如:

1. #引入 gc 库
2. import gc
3. tt = 'hello'
4. #定义一个包含多个类型的 list
5. list1 = [1,4,tt,3.4,"yes",[1,2]]
6. del list1
7. #回收内存地址
8. gc.collect()

系统为了提升性能,会将一部分变量驻留在内存中。这个机制对于多线程并发时程序产生大量占用内存的变量无法得到释放,或者某些不再需要使用的全局变量占用着大的内存,导致后续运行中出现内存不足的情况,此时就可以使用 del 关键字来回收内存,使系统的性能得以提升。同时,它可以为团队省去扩充大量内存的成本。

Python range()快速初始化数字列表

创建这样一个列表,其中包含前 10 个整数(即 1~10)的平方,实现代码如下:

1. squares = []
2. for value in range(1,11):
3. square = value**2
4. squares.append(square)
5. print(squares)

运行结果为:

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Python list 列表实现栈和队列

队列和栈是两种数据结构,其内部都是按照固定顺序来存放变量的,二者的区别在于对数据的存取顺序:
• 队列是,先存入的数据最先取出,即“先进先出”。
• 栈是,最后存入的数据最先取出,即“后进先出”。

Python list 实现队列

使用 list 列表模拟队列功能的实现方法是,定义一个 list 变量,存入数据时使用 insert() 方法,设置其第一个参数为 0,即表示每次都从最前面插入数据;读取数据时,使用 pop() 方法,即将队列的最后一个元素弹出。
如此 list 列表中数据的存取顺序就符合“先进先出”的特点。实现代码如下:

1. #定义一个空列表,当做队列
2. queue = []
3. #向列表中插入元素
4. queue.insert(0,1)
5. queue.insert(0,2)
6. queue.insert(0,"hello")
7. print(queue)
8. print("取一个元素:",queue.pop())
9. print("取一个元素:",queue.pop())
10. print("取一个元素:",queue.pop())

运行结果为:

['hello', 2, 1]
取一个元素: 1
取一个元素: 2
取一个元素: hello

Python list 实现栈

使用 list 列表模拟栈功能的实现方法是,使用 append() 方法存入数据;使用 pop() 方法读取数据。
append() 方法向 list 中存入数据时,每次都在最后面添加数据,这和前面程序中的 insert() 方法正好相反。
举个例子:

1. #定义一个空 list 当做栈
2. stack = []
3. stack.append(1)
4. stack.append(2)
5. stack.append("hello")
6. print(stack)
7. print("取一个元素:",stack.pop())
8. print("取一个元素:",stack.pop())
9. print("取一个元素:",stack.pop())

输出结果为:

[1, 2, 'hello']
取一个元素: hello
取一个元素: 2
取一个元素: 1

collections 模块实现栈和队列

前面使用 list 实现队列的例子中,插入数据的部分是通过 insert() 方法实现的,这种方法效率并不高,因为每次从列表的开头插入一个数据,列表中所有元素都得向后移动一个位置。
这里介绍一个相对更高效的方法,即使用标准库的 collections 模块中的 deque 结构体,它被设计成在两端存入和读取都很快的特殊 list,可以用来实现栈和队列的功能。

1. queueAndStack = deque()
2. queueAndStack.append(1)
3. queueAndStack.append(2)
4. queueAndStack.append("hello")
5. print(list(queueAndStack))
6.
7. #实现队列功能,从队列中取一个元素,根据先进先出原则,这里应输出 1
8. print(queueAndStack.popleft())
9. #实现栈功能,从栈里取一个元素,根据后进先出原则,这里应输出 hello
10. print(queueAndStack.pop())
11. #再次打印列表
12. print(list(queueAndStack))

输出结果为:

[1, 2, 'hello']
1
hello
[2]
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骑着骆驼去南极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值