当前位置: 首页 > news >正文

一文吃透 Python 列表:从定义到拷贝,7 大操作一网打尽

1. 列表的定义

在 Python 中,列表(list)是一种有序、可变的容器类型,用于存储多个元素。所谓"有序"是指列表中每个元素都有固定的位置(索引),插入顺序会被保留;"可变"则意味着创建后可以随时增删改其中的元素,这与元组(tuple)字符串(str)等不可变类型有明显区别。

定义列表有以下两种常用方式:

  • 使用方括号[]:最直接的方式,在方括号内用逗号分隔各个元素,即可创建包含初始元素的列表。写成[]则表示空列表。
  • 使用list()构造函数:将可迭代对象(如字符串、元组、range 对象、集合等)转换为列表,这对于动态生成列表或从其他数据结构转换非常实用。

这里需要解释一下可迭代对象(iterable)的概念:凡是能被for循环遍历的对象,都属于可迭代对象。常见的有字符串(遍历每个字符)、range 对象(遍历整数序列)、元组、集合、字典的键等。将可迭代对象传入list()后,会把其中的每个元素依次提取出来,形成一个新的列表。

# 方式一:使用方括号定义 empty = [] # 空列表 nums = [10, 20, 30] # 包含三个整数的列表 print(empty, type(empty)) # [] <class 'list'> print(nums, type(nums)) # [10, 20, 30] <class 'list'> 方式二:使用 list() 构造函数 chars = list("hello") # 字符串 → 列表,每个字符成为一个元素 print(chars) # ['h', 'e', 'l', 'l', 'o'] numbers = list(range(5)) # range 对象 → 列表 print(numbers) # [0, 1, 2, 3, 4] 空列表的两种写法 a = [] b = list() print(a, b) # [] []

2. 列表中可以放入任意内容

Python 列表的最大特点之一就是类型不受限制。同一个列表中可以同时存放整数、浮点数、字符串、布尔值,甚至还能嵌套其他列表、字典或自定义对象。这种灵活性让列表非常适合用来组织异构数据,比如一条记录中同时包含姓名、年龄、成绩列表等字段。

嵌套结构在实际开发中很常见,例如用列表存储多个学生的成绩单(每个学生又是一个列表),或者用列表存储从 JSON 接口解析出的字典对象。不过也正因为这种灵活性,在处理嵌套列表时需要格外注意:修改嵌套的可变对象(如子列表)会同时影响引用它的地方,这一点在后面浅拷贝一节会详细说明。

# 混合存放不同类型的数据 info = ["张三", 25, 89.5, True, ["数学", "英语"]] print(info) # ['张三', 25, 89.5, True, ['数学', '英语']] 嵌套字典示例 students = [ {"name": "小明", "score": 92}, {"name": "小红", "score": 88} ] print(students[0]["name"]) # 小明 甚至可以存放 None data = [1, None, "abc"] print(data) # [1, None, 'abc']

3. 索引与遍历

列表中的每个元素都有一个位置编号,称为索引(index)。Python 的索引从0开始计数,也就是说第一个元素的索引是 0,第二个是 1,以此类推。最后一个元素的索引是len(列表) - 1

除了正向索引,Python 还支持负数索引,即从列表末尾反向访问:-1表示最后一个元素,-2表示倒数第二个元素,以此类推。这在需要快速获取尾部元素时非常方便,不需要先计算列表长度。使用内置函数len()可以获取列表的元素个数(即长度)。

fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"] 正向索引 print(fruits[0]) # 苹果 —— 第一个 print(fruits[2]) # 橙子 —— 第三个 负数索引 print(fruits[-1]) # 西瓜 —— 最后一个 print(fruits[-3]) # 橙子 —— 倒数第三个 len() 获取长度 print(len(fruits)) # 5

遍历列表是对每个元素逐一执行相同操作的过程,Python 提供了两种主流方式:

  • 直接遍历元素——使用for 变量 in 列表的语法,循环变量会依次获取列表中的每个元素值。这种方式简洁直观,适用于只需要读取元素内容、不需要知道它排在第几个的场景。
  • 通过索引遍历——借助range(len(列表))生成一个从 0 到 len-1 的整数序列,然后在循环体内用列表[i]访问每个元素。这种方式适合需要同时知道位置和内容的场景,比如修改某个位置的元素,或者需要比较相邻元素。
scores = [85, 92, 78, 95, 88] 方式一:直接遍历元素 —— 最常用 for s in scores: print(s) 方式二:通过索引遍历 —— 需要位置信息时使用 for i in range(len(scores)): print(f"第{i}个学生成绩:{scores[i]}")

索引遍历实战:判断列表是否对称(回文)

所谓"对称"是指列表从前往后读和从后往前读完全一样,例如[1, 2, 3, 2, 1]。利用首尾配对比较的思路:将第i个元素与倒数第i个元素逐一比较,只要有一对不相等,就可以判定为不对称并提前退出。由于每轮比较首尾两个元素,只需循环到列表长度的一半即可。

nums = [1, 2, 3, 2, 1] length = len(nums) is_symmetric = True for i in range(length // 2): # nums[i] 与 nums[length - 1 - i] 是"对称位置" if nums[i] != nums[length - 1 - i]: is_symmetric = False print(f"不对称:{nums[i]} != {nums[length - 1 - i]}") break if is_symmetric: print("列表对称") 更简洁的方法:直接与反转后的列表比较 print(nums == nums[::-1]) # True

4. 列表的常见操作

Python 为列表提供了丰富的内置方法,涵盖查找、统计、插入、删除、排序、反转和拷贝等日常开发中的高频需求。下面逐一介绍这些方法的用法和注意事项。

4.1 index —— 查找元素位置

index(value)方法用于查找指定值在列表中第一次出现的位置,返回其索引。如果列表中不存在该值,则会抛出 ValueError 异常导致程序中断。因此在实际使用中,建议先使用in运算符判断元素是否存在,再调用index(),这是一种稳健的编码习惯。

如果列表中包含多个相同的值,index()只返回第一个匹配项的索引,后面的同名元素需要额外处理(比如切片后再查找)。

colors = ["红", "蓝", "绿", "蓝", "黄"] 查找第一个"蓝"的位置 print(colors.index("蓝")) # 输出 1 如果要查找的值不存在,会抛出异常 colors.index("紫") # ValueError: '紫' is not in list 安全做法:先用 in 判断 target = "紫" if target in colors: print(colors.index(target)) else: print(f"{target} 不在列表中")

4.2 count —— 统计元素出现次数

count(value)方法统计某个值在列表中出现的总次数。如果该元素不存在,则返回0,不会抛出异常。这个方法常用于统计词频、判断重复数据等场景。

votes = ["赞成", "反对", "赞成", "赞成", "弃权"] print(votes.count("赞成")) # 3 print(votes.count("反对")) # 1 print(votes.count("无效")) # 0 —— 不存在返回 0,不会报错

4.3 插入操作

列表提供了三种向其中添加元素的方法,分别适用于不同的插入需求:

方法说明示例
append(obj)将单个元素追加到列表末尾,这是最常用的添加方式items.append(4)
insert(index, obj)指定索引位置插入元素,原位置及之后的元素依次后移items.insert(0, "开头")
extend(iterable)将可迭代对象中的每个元素逐个追加到末尾,相当于批量添加items.extend([5, 6, 7])

需要注意的是:append()是把参数作为一个整体追加,即使传入了列表也不会展开;而extend()会遍历参数中的每个元素,逐个添加到末尾。这两者的区别在初学者中常被混淆。

items = [1, 2, 3] append —— 追加单个元素 items.append(4) print(items) # [1, 2, 3, 4] insert —— 在指定位置插入 items.insert(0, "start") # 在索引 0 处插入 print(items) # ['start', 1, 2, 3, 4] items.insert(2, "mid") # 在索引 2 处插入 print(items) # ['start', 1, 'mid', 2, 3, 4] extend —— 批量追加 items.extend([5, 6, 7]) print(items) # ['start', 1, 'mid', 2, 3, 4, 5, 6, 7] append 和 extend 的区别 a = [1, 2] a.append([3, 4]) # 把 [3, 4] 作为单个元素追加 print(a) # [1, 2, [3, 4]] b = [1, 2] b.extend([3, 4]) # 把 [3, 4] 中的元素逐个追加 print(b) # [1, 2, 3, 4]

4.4 删除操作

列表支持多种删除元素的方式,可以按位置或者一次性清空来移除元素。下表汇总了四种删除方法:

方法说明返回值
pop()删除并返回末尾元素,类似"弹出"栈顶被删除的元素
pop(index)删除并返回指定索引的元素,索引越界会报错被删除的元素
remove(value)删除第一个匹配的指定值,不存在则抛出 ValueError无(返回 None)
clear()清空整个列表,移除所有元素无(返回 None)

pop()的有用之处在于它既能删除元素,又能返回被删除的值,这在实现栈(后进先出)或队列等数据结构时非常方便。remove()只删除第一个匹配项,如果列表中有多个相同的值需要全部删除,则需要配合循环使用。

tasks = ["任务A", "任务B", "任务C", "任务D", "任务E"] pop() —— 删除并返回末尾元素 last = tasks.pop() print(last) # 任务E print(tasks) # ['任务A', '任务B', '任务C', '任务D'] pop(index) —— 删除并返回指定位置元素 first = tasks.pop(0) print(first) # 任务A print(tasks) # ['任务B', '任务C', '任务D'] remove() —— 按值删除第一个匹配项 tasks.append("任务B") # 先添加一个重复元素 print(tasks) # ['任务B', '任务C', '任务D', '任务B'] tasks.remove("任务B") # 删除第一个"任务B" print(tasks) # ['任务C', '任务D', '任务B'] 安全做法:先判断值是否存在再删除 if "任务X" in tasks: tasks.remove("任务X") clear() —— 清空整个列表 tasks.clear() print(tasks) # []

4.5 排序 —— sort

sort()方法对列表进行原地排序(in-place),即直接修改原列表的元素顺序,不创建新列表。默认按升序排列(从小到大),设置reverse=True则按降序排列(从大到小)。

需要注意:sort()只能用于元素类型相同的列表(如全是数字或全是字符串),否则 Python 无法比较不同类型的大小,会抛出 TypeError。如果希望保留原列表不变、只返回排序后的新列表,可以使用内置函数sorted(),它会生成一个新的排序列表而不会修改原列表。

scores = [72, 95, 88, 60, 91, 85] 升序排序 scores.sort() print(scores) # [60, 72, 85, 88, 91, 95] 降序排序 scores.sort(reverse=True) print(scores) # [95, 91, 88, 85, 72, 60] sorted() 返回新列表,原列表不变 original = [3, 1, 4, 1, 5] result = sorted(original) print(result) # [1, 1, 3, 4, 5] print(original) # [3, 1, 4, 1, 5] —— 原列表未变

4.6 逆序 —— reverse

reverse()方法将列表中的元素首尾反转,即第一个变成最后一个、第二个变成倒数第二个,以此类推。它与排序不同,不涉及元素之间的大小比较,只是纯粹地颠倒顺序。这在需要回放历史记录、逆向遍历等场景中很实用。

如果想要顺序反转但不修改原列表,可以使用切片列表[::-1]生成一个反转后的新列表。

letters = ["a", "b", "c", "d", "e"] 原地反转 letters.reverse() print(letters) # ['e', 'd', 'c', 'b', 'a'] 再次反转则恢复原顺序 letters.reverse() print(letters) # ['a', 'b', 'c', 'd', 'e'] 使用切片生成反转后的新列表(不修改原列表) reversed_letters = letters[::-1] print(reversed_letters) # ['e', 'd', 'c', 'b', 'a'] print(letters) # ['a', 'b', 'c', 'd', 'e'] —— 原列表不变

4.7 浅拷贝 —— copy(补充)

copy()方法返回列表的浅拷贝(shallow copy)。浅拷贝意味着新列表会复制原列表中每个元素的引用,而不是递归地复制元素本身。具体影响如下:

  • 对于不可变元素(如整数、字符串、元组等),修改新列表中的这类元素不会影响原列表,因为不可变元素被替换时会指向新对象。
  • 对于可变元素(如嵌套的子列表、字典等),新列表和原列表共享同一个内部对象。修改新列表中嵌套对象的内部内容,原列表中的对应嵌套对象也会同步变化。

如果需要完全独立的副本(连嵌套对象也复制),应使用copy模块中的deepcopy()方法进行深拷贝

import copy original = [1, 2, [10, 20]] 浅拷贝 shallow = original.copy() 修改不可变元素 —— 不影响原列表 shallow[0] = 999 print(original) # [1, 2, [10, 20]] —— 不变 修改嵌套列表中的元素 —— 会影响原列表! shallow[2][0] = 888 print(original) # [1, 2, [888, 20]] —— 原列表被联动修改 深拷贝 —— 完全独立的副本 original2 = [1, 2, [10, 20]] deep = copy.deepcopy(original2) deep[2][0] = 999 print(original2) # [1, 2, [10, 20]] —— 原列表不受影响 print(deep) # [1, 2, [999, 20]]
http://www.cnnetsun.cn/news/3505683.html

相关文章:

  • Android开发入门:环境搭建与基础架构解析
  • n8n与FastAPI构建小红书AI内容矩阵实战
  • 国产Cortex-M高主频MCU选型与应用指南
  • 2027年信息系统项目管理师备考,先把这条路线看懂
  • 救命!2026年AI论文软件排行榜,选题卡壳的毕业生直接抄作业
  • 2026年度10款降AI率软件红黑榜!优缺点无保留曝光,达标率硬核对标行业天花板
  • Anthropic的skill-creator使用分享
  • 从奶嘴到围兜:硅胶如何守护宝宝的每一刻
  • 青岛船员管理系统开题报告
  • ZBrush 2026.2.1免安装绿色版:解压即用的3D建模解决方案
  • 麒麟操作系统-----安装教程
  • 解决Blender FBX导入Unity贴图丢失:材质系统差异与标准化导出流程
  • 玉币杯小巧圆润,刚好合在掌心
  • 手术钳夹住血管那一刻,焊缝撑不住怎么办?
  • 数据科学面试的Outlier思维:从业务语境重构技术表达
  • Spring Boot项目中批量文本替换的最佳实践
  • 写代码越来越便宜,为什么企业数字化反而更难做了?
  • 公司刚成立,到底要不要记账报税?
  • Unity 3D中实现可交互液晶屏幕:Render Texture与World Space Canvas实战
  • 数据正常性诊断:构建可解释的动态基线与自证系统
  • 第一关:蘑菇王国的入口
  • 信息的本质是什么
  • 从脚本到应用:给 Web 加个安全的问答接口
  • 《2001:太空漫游》(2001: A Space Odyssey)中的黑曜石状长方体,其实不是普通意义上的“外星设备”,它更像一个关于人类进化、意识、技术和宇宙意义的哲学符号
  • ChatGPT语音交互技术解析:从原理到开发实践
  • C++延时队列实现:从优先队列到订单超时实战
  • ARMv8-A调试架构与AM62L处理器外部调试寄存器深度解析
  • PhoneBindPage:更换手机号表单设计与验证
  • 单位时间内,你进行了多少次有效尝试。
  • 真正的梦想,会逼迫你发展过去没有的能力。