跳到主要内容
Python 常用数据结构:列表操作与生成式详解 | 极客日志
Python AI 算法
Python 常用数据结构:列表操作与生成式详解 综述由AI生成 Python 列表的核心操作方法,包括元素的添加(append、insert)、删除(remove、pop、del、clear)、查找(index、count)以及排序(sort、reverse)。重点讲解了列表生成式的语法优势及三种典型应用场景,对比了其与常规循环的性能差异。此外,文章深入探讨了嵌套列表的构建方式、访问技巧及浅拷贝陷阱,并通过双色球随机选号的完整案例演示了列表在实际编程中的应用。最后总结了列表底层原理及开发中的最佳实践,帮助读者建立扎实的列表操作基础。
二进制 发布于 2025/2/6 更新于 2026/6/2 21 浏览Python 常用数据结构:列表操作与生成式详解
列表的方法
列表类型的变量拥有很多方法可以帮助我们操作一个列表。假设我们有名为 foos 的列表,列表有名为 bar 的方法,那么使用列表方法的语法是:foos.bar()。这是一种通过对象引用调用对象方法的语法,也称为给对象发消息。
添加和删除元素
列表是一种可变容器,我们可以向容器中添加元素、从容器移除元素,也可以修改现有容器中的元素。我们可以使用列表的 append 方法向列表中追加元素,使用 insert 方法向列表中插入元素。追加指的是将元素添加到列表的末尾,而插入则是在指定的位置添加新元素。
languages = ['Python' , 'Java' , 'C++' ]
languages.append('JavaScript' )
print (languages)
languages.insert(1 , 'SQL' )
print (languages)
我们可以用列表的 remove 方法从列表中删除指定元素。需要注意的是,如果要删除的元素并不在列表中,会引发 ValueError 错误导致程序崩溃,所以建议大家在删除元素时,先用成员运算做一个判断。我们还可以使用 pop 方法从列表中删除元素,pop 方法默认删除列表中的最后一个元素,当然也可以给一个位置,删除指定位置的元素。在使用 pop 方法删除元素时,如果索引的值超出了范围,会引发 IndexError 异常,导致程序崩溃。除此之外,列表还有一个 clear 方法,可以清空列表中的元素。
languages = ['Python' , 'SQL' , 'Java' , 'C++' , 'JavaScript' ]
if 'Java' in languages:
languages.remove('Java' )
if 'Swift' in languages:
languages.remove('Swift' )
print (languages)
languages.pop()
temp = languages.pop(1 )
print (temp)
languages.append(temp)
(languages)
languages.clear()
(languages)
print
print
说明 :pop 方法删除元素时会得到被删除的元素,上面的代码中,我们将 pop 方法删除的元素赋值给了名为 temp 的变量。当然如果你愿意,还可以把这个元素再次加入到列表中,正如上面的代码 languages.append(temp) 所做的那样。
这里还有一个小问题,例如 languages 列表中有多个 'Python',那么我们用 languages.remove('Python') 是删除所有的 'Python',还是删除第一个 'Python'?大家可以先猜一猜,然后再自己动手尝试一下。实际上,remove 只删除第一个匹配的元素。
从列表中删除元素其实还有一种方式,就是使用 Python 中的 del 关键字后面跟要删除的元素,这种做法跟使用 pop 方法指定索引删除元素没有实质性的区别,但后者会返回删除的元素,前者在性能上略优,因为 del 对应的底层字节码指令是 DELETE_SUBSCR,而 pop 对应的底层字节码指令是 CALL_METHOD 和 POP_TOP。
items = ['Python' , 'Java' , 'C++' ]
del items[1 ]
print (items)
元素位置和频次 列表的 index 方法可以查找某个元素在列表中的索引位置,如果找不到指定的元素,index 方法会引发 ValueError 错误;列表的 count 方法可以统计一个元素在列表中出现的次数。
items = ['Python' , 'Java' , 'Java' , 'C++' , 'Kotlin' , 'Python' ]
print (items.index('Python' ))
print (items.index('Python' , 1 ))
print (items.count('Python' ))
print (items.count('Kotlin' ))
print (items.count('Swift' ))
print (items.index('Java' , 3 ))
元素排序和反转 列表的 sort 操作可以实现列表元素的排序,而 reverse 操作可以实现元素的反转。
items = ['Python' , 'Java' , 'C++' , 'Kotlin' , 'Swift' ]
items.sort()
print (items)
items.reverse()
print (items)
列表生成式 在 Python 中,列表还可以通过一种特殊的字面量语法来创建,这种语法叫做生成式。下面,我们通过例子来说明使用列表生成式创建列表到底有什么好处。
场景一:筛选数字 创建一个取值范围在 1 到 99 且能被 3 或者 5 整除的数字构成的列表。
items = []
for i in range (1 , 100 ):
if i % 3 == 0 or i % 5 == 0 :
items.append(i)
print (items)
items = [i for i in range (1 , 100 ) if i % 3 == 0 or i % 5 == 0 ]
print (items)
场景二:元素变换 有一个整数列表 nums1,创建一个新的列表 nums2,nums2 中的元素是 nums1 中对应元素的平方。
nums1 = [35 , 12 , 97 , 64 , 55 ]
nums2 = [num ** 2 for num in nums1]
print (nums2)
场景三:条件过滤 有一个整数列表 nums1,创建一个新的列表 nums2,将 nums1 中大于 50 的元素放到 nums2 中。
nums1 = [35 , 12 , 97 , 64 , 55 ]
nums2 = [num for num in nums1 if num > 50 ]
print (nums2)
使用列表生成式创建列表不仅代码简单优雅,而且性能上也优于使用 for-in 循环和 append 方法向空列表中追加元素的方式。这是因为 Python 解释器的字节码指令中有专门针对生成式的指令(LIST_APPEND 指令);而 for 循环是通过方法调用的方式为列表添加元素,方法调用本身就是一个相对比较耗时的操作。
嵌套列表 Python 语言没有限定列表中的元素必须是相同的数据类型,也就是说一个列表中的元素可以是任意的数据类型,当然也包括列表本身。如果列表中的元素也是列表,那么我们可以称之为嵌套的列表。嵌套的列表可以用来表示表格或数学上的矩阵。
例如:我们想保存 5 个学生 3 门课程的成绩,可以用如下所示的列表。
scores = [[95 , 83 , 92 ], [80 , 75 , 82 ], [92 , 97 , 90 ], [80 , 78 , 69 ], [65 , 66 , 89 ]]
print (scores[0 ])
print (scores[0 ][1 ])
对于上面的嵌套列表,每个元素相当于就是一个学生 3 门课程的成绩,例如 [95, 83, 92],而这个列表中的 83 代表了这个学生某一门课的成绩。如果想访问这个值,可以使用两次索引运算 scores[0][1],其中 scores[0] 可以得到 [95, 83, 92] 这个列表,再次使用索引运算 [1] 就可以获得该列表中的第二个元素。
嵌套列表的初始化 如果想通过键盘输入的方式来录入 5 个学生 3 门课程的成绩并保存在列表中,可以使用如下所示的代码。
scores = []
for _ in range (5 ):
temp = []
for _ in range (3 ):
score = int (input ('请输入成绩:' ))
temp.append(score)
scores.append(temp)
print (scores)
如果想通过产生随机数的方式来生成 5 个学生 3 门课程的成绩并保存在列表中,我们可以使用列表生成式。
import random
scores = [[random.randrange(60 , 101 ) for _ in range (3 )] for _ in range (5 )]
print (scores)
注意 :上面的代码 [random.randrange(60, 101) for _ in range(3)] 可以产生由 3 个随机整数构成的列表,我们把这段代码又放在了另一个列表生成式中作为列表的元素,这样的元素一共生成 5 个,最终得到了一个嵌套列表。
嵌套列表的陷阱 在处理嵌套列表时,需要特别注意浅拷贝的问题。如果使用 * 运算符或切片复制外层列表,内层列表仍然是引用同一个对象。这可能导致修改其中一个子列表时,意外影响其他子列表。
wrong_scores = [[]] * 5
wrong_scores[0 ].append(95 )
print (wrong_scores)
right_scores = [[] for _ in range (5 )]
right_scores[0 ].append(95 )
print (right_scores)
列表应用举例 下面我们通过一个双色球随机选号的例子为大家讲解列表的应用。双色球是由中国福利彩票发行管理中心发售的乐透型彩票,每注投注号码由 6 个红色球和 1 个蓝色球组成。红色球号码从 1 到 33 中选择,蓝色球号码从 1 到 16 中选择。每注需要选择 6 个红色球号码和 1 个蓝色球号码。
下面,我们通过 Python 程序来生成一组随机号码。
"""
双色球随机选号程序
Version: 1.0
"""
import random
red_balls = list (range (1 , 34 ))
selected_balls = []
for _ in range (6 ):
index = random.randrange(len (red_balls))
selected_balls.append(red_balls.pop(index))
selected_balls.sort()
for ball in selected_balls:
print (f'\033[031m{ball:0 >2d} \033[0m' , end=' ' )
blue_ball = random.randrange(1 , 17 )
print (f'\033[034m{blue_ball:0 >2d} \033[0m' )
说明 :上面代码中 print(f'\033[0m...\033[0m') 是为了控制输出内容的颜色,红色球输出成红色,蓝色球输出成蓝色。其中省略号代表我们要输出的内容,\033[0m 是一个控制码,表示关闭所有属性。
我们还可以利用 random 模块提供的 sample 和 choice 函数来简化上面的代码,前者可以实现无放回随机抽样,后者可以实现随机抽取一个元素。
"""
双色球随机选号程序
Version: 1.1
"""
import random
red_balls = [i for i in range (1 , 34 )]
blue_balls = [i for i in range (1 , 17 )]
selected_balls = random.sample(red_balls, 6 )
selected_balls.sort()
for ball in selected_balls:
print (f'\033[031m{ball:0 >2d} \033[0m' , end=' ' )
blue_ball = random.choice(blue_balls)
print (f'\033[034m{blue_ball:0 >2d} \033[0m' )
如果要实现随机生成 N 注号码,我们只需要将上面的代码放到一个 N 次的循环中。
"""
双色球随机选号程序
Version: 1.2
"""
import random
n = int (input ('生成几注号码:' ))
red_balls = [i for i in range (1 , 34 )]
blue_balls = [i for i in range (1 , 17 )]
for _ in range (n):
selected_balls = random.sample(red_balls, 6 )
selected_balls.sort()
for ball in selected_balls:
print (f'\033[031m{ball:0 >2d} \033[0m' , end=' ' )
blue_ball = random.choice(blue_balls)
print (f'\033[034m{blue_ball:0 >2d} \033[0m' )
总结与最佳实践 Python 中的列表底层是一个可以动态扩容的数组,列表元素在计算机内存中是连续存储的,所以可以实现随机访问(通过一个有效的索引获取对应的元素且操作时间与列表元素个数无关)。我们可以暂时不去触碰这些底层的存储细节,也不需要大家理解列表每个方法的渐近时间复杂度,大家先学会用列表解决工作中的问题,这一点更为重要。
优先使用列表生成式 :相比传统的 for 循环加 append,列表生成式通常具有更好的可读性和执行效率。
注意可变对象的引用 :在初始化嵌套列表时,避免使用 [[None]*n]*m 这种写法,应使用列表推导式确保每个子列表都是独立的对象。
合理使用内置方法 :如 in 操作符用于成员检查比遍历更高效,extend 方法用于合并列表比多次 append 更简洁。
避免在遍历时修改列表 :如果在遍历列表的同时修改其长度,可能会导致索引越界或跳过元素,建议使用列表生成式创建新列表代替原地修改。
掌握列表的这些特性和操作方法,是学习 Python 数据处理的基础。后续章节将介绍元组、字典等更多数据结构,它们共同构成了 Python 强大的数据操作能力。
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
随机西班牙地址生成器 随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online