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

Python3 列表(List)详解手册

1. 开篇:列表的本质与哲学

1.1 什么是列表?

列表是Python中最基本、最常用的数据结构之一。它是一个有序的、可变的元素集合。你可以把它想象成一个“超级容器”,可以容纳任何类型的数据:数字、字符串、布尔值,甚至是其他列表(即嵌套列表)或更复杂的对象。

从C/C++背景来看,Python的列表是一种动态数组(Dynamic Array)。这意味着:

  • 有序:元素有固定的位置(索引),从0开始。
  • 可变:你可以在创建列表后添加、删除或修改其中的元素。
  • 动态:无需预先声明大小,它会自动增长或收缩以适应存储的元素。
  • 异构:一个列表可以同时包含intfloatstrbool甚至其他list
1.2 为什么列表如此重要?

列表不仅是存储数据的基本方式,更是实现许多算法(如栈、队列)和数据处理流程的基石。无论是处理一个班级的学生名单、一系列网络请求的响应,还是作为机器学习的数据批次,列表都是首选工具。列表推导式(List Comprehension)更是Python简洁优雅的代码风格的代表。

1.3 列表的核心特性一览
特性描述
有序性元素顺序被保留,可通过索引访问。
可变性支持append,insert,pop,sort等原地修改操作。
动态性不需要声明长度,可以随时增加或减少元素。
异构性一个列表可以包含任意不同类型的对象。
可迭代性可以方便地使用for循环遍历。

2. 列表的创建与初始化

2.1 使用方括号[]

这是最直接、最Pythonic的方式。

# 创建一个空列表 empty_list = [] print(empty_list) # 输出: [] # 创建一个包含混合类型元素的列表 mixed_list = [1, "hello", 3.14, True, [5, 6]] print(mixed_list) # 输出: [1, 'hello', 3.14, True, [5, 6]] # 创建一个数字列表 numbers = [1, 2, 3, 4, 5]
2.2 使用list()构造函数

list()是一个内置函数,可以将其它可迭代对象(如字符串、元组、集合、字典的键、range对象等)转换为列表。

# 将字符串转换为字符列表 char_list = list("Python") print(char_list) # 输出: ['P', 'y', 't', 'h', 'o', 'n'] # 将元组转换为列表 tuple_to_list = list((1, 2, 3)) print(tuple_to_list) # 输出: [1, 2, 3] # 将range对象转换为列表 range_to_list = list(range(5)) print(range_to_list) # 输出: [0, 1, 2, 3, 4]
2.3 列表推导式(List Comprehension)

这是创建列表最强大的方式之一,用于从一个可迭代对象中通过表达式和条件筛选快速生成新列表。

# 创建一个包含0-9平方的列表 squares = [x**2 for x in range(10)] print(squares) # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # 创建一个只包含偶数的列表 evens = [x for x in range(20) if x % 2 == 0] print(evens) # 输出: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
2.4 创建空列表与单元素列表
  • 空列表:[]list()
  • 单元素列表:['a'][1]。注意,在元组中单元素需要加逗号,但列表不需要。
single_element = print(single_element) # 输出:

3. 列表元素的访问与索引

列表索引是定位元素的方式,从0开始计数。

3.1 正向索引
fruits = ['apple', 'banana', 'cherry', 'date'] print(fruits # 输出: apple print(fruits[2](@ref) # 输出: cherry print(fruits[3](@ref) # 输出: date
3.2 反向索引

Python 支持从列表末尾开始计数,最后一个元素的索引是-1,倒数第二个是-2,依此类推。

print(fruits[-1]) # 输出: date print(fruits[-2]) # 输出: cherry print(fruits[-3]) # 输出: banana
3.3 检查元素是否存在 (innot in)

使用in关键字可以快速判断一个元素是否在列表中。

if 'banana' in fruits: print("Banana is in the list!") # 会输出 if 'grape' not in fruits: print("Grape is not in the list.") # 会输出

4. 列表的切片操作 (Slicing)

切片是从列表中提取一个子列表的强大方法,语法为list[start:stop:step]。遵循左闭右开原则(包含 start,不包含 stop)。

4.1 基本切片语法 [start:stop:step]
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 获取索引2到5(不含5)的元素 sub_list = numbers[2:5] print(sub_list) # 输出: [2, 3, 4] # 从索引1开始,每隔2个元素取一个,直到索引7 sub_list_step = numbers[1:8:2] print(sub_list_step) # 输出: [1, 3, 5, 7]
4.2 省略索引的用法
  • list[:stop]: 从开始取到stop之前。
  • list[start:]: 从start取到末尾。
  • list[:]: 取整个列表,这是创建浅拷贝的常用方式。
print(numbers[:5]) # [0, 1, 2, 3, 4] print(numbers[5:]) # [5, 6, 7, 8, 9] print(numbers[:]) # 创建一个浅拷贝
4.3 负步长实现反转

step为负数时,切片从右向左进行,常用于反转列表。

reversed_list = numbers[::-1] print(reversed_list) # 输出: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
4.4 切片的深度拷贝特性

切片操作返回的是原列表的一个浅拷贝。这意味着,对于简单元素(如整数、字符串),修改切片不会影响原列表。但对于嵌套对象(如列表中的列表),修改嵌套对象会影响原对象。

original = [[1, 2], [3, 4]] slice_copy = original[:] slice_copy[0] = 99 print(original) # 输出: [[99, 2], [3, 4]] 原列表被影响!

5. 列表的增删改查(CRUD)

5.1 增 (Create)
方法/操作描述示例
append(x)在列表末尾添加元素xlist.append(10)
insert(i, x)索引i插入元素xlist.insert(0, 'start')
extend(iter)将可迭代对象iter中的所有元素添加到末尾。list.extend([4](@ref)[5](@ref)[6](@ref)
+运算符将两个列表拼接成一个新列表。new_list = [1,2] + [3,4]
*运算符将列表重复指定次数,生成新列表。repeated = ['a'] * 3

示例:

fruits = ['apple', 'banana'] fruits.append('cherry') # ['apple', 'banana', 'cherry'] fruits.insert(1, 'blueberry') # ['apple', 'blueberry', 'banana', 'cherry'] fruits.extend(['date', 'elderberry']) # ['apple', 'blueberry', 'banana', 'cherry', 'date', 'elderberry'] new_list = fruits + ['fig'] # 创建一个新列表
5.2 删 (Delete)
方法/语句描述示例
pop(i)移除并返回索引i处的元素。若不指定i,则移除并返回最后一个元素。last = list.pop();first = list.pop(0)
remove(x)移除列表中第一个值为x的元素。若元素不存在,抛出ValueErrorlist.remove('banana')
del list[i]删除索引i处的元素。也支持切片删除del list[a:b]del list[2];del list[1:3]
clear()删除列表中的所有元素。list.clear()

示例:

fruits = ['apple', 'banana', 'cherry', 'banana'] last_fruit = fruits.pop() # 移除并返回 'banana'; fruits: ['apple', 'banana', 'cherry'] fruits.remove('banana') # 移除第一个 'banana'; fruits: ['apple', 'cherry'] del fruits[0] # 移除 'apple'; fruits: ['cherry'] fruits.clear() # fruits: []
5.3 改 (Update)
方法/操作描述示例
直接赋值通过索引直接修改元素。list[0] = 'new_value'
切片赋值将切片替换为一个新序列,序列长度可以不同。list[1:3] = ['a', 'b', 'c']
reverse()原地反转列表顺序。list.reverse()
sort()原地对列表进行排序(修改原列表)。可指定keyreverselist.sort();list.sort(reverse=True)

示例:

numbers = [3, 1, 2] numbers[0] = 10 # numbers: [10, 1, 2] numbers.sort() # numbers: [1, 2, 10] numbers.reverse() # numbers: [10, 2, 1]
5.4 查 (Read/Query)
方法/函数描述示例
index(x[, start[, end]])返回第一个值为x的元素的索引。可指定搜索范围。若未找到,抛出ValueErrorlist.index('banana');list.index('banana', 2)
count(x)返回元素x在列表中出现的次数。list.count('apple')
len(list)返回列表中元素的个数。length = len(list)
max(list)返回列表中的最大值(元素需可比较)。max_value = max(list)
min(list)返回列表中的最小值(元素需可比较)。min_value = min(list)

示例:

fruits = ['apple', 'banana', 'cherry', 'banana'] print(fruits.index('banana')) # 输出: 1 print(fruits.count('banana')) # 输出: 2 print(len(fruits)) # 输出: 4

6. 列表的高级主题

6.1 列表的拷贝:浅拷贝与深拷贝
  • 浅拷贝(Shallow Copy):创建一个新列表,但其元素是原列表元素的引用。修改新列表中的可变对象(如嵌套列表)会影响原列表。

    • 方法:list.copy(),list[:],list()构造函数
  • 深拷贝(Deep Copy):递归地创建一个新列表,新列表中的元素是完全独立的副本。修改新列表中的任何对象都不会影响原列表。

    • 方法:import copy; new_list = copy.deepcopy(original)
import copy original = [[1, 2], [3, 4]] shallow_copy = original[:] deep_copy = copy.deepcopy(original) shallow_copy[0] = 99 print(original) # 输出: [[99, 2], [3, 4]] (被修改) deep_copy[0] = 0 print(original) # 输出: [[99, 2], [3, 4]] (未被修改)
6.2 列表作为栈和队列
  • 栈(Stack):后进先出(LIFO)。使用append()入栈,pop()出栈。
  • 队列(Queue):先进先出(FIFO)。虽然可以用pop(0)append()实现,但效率极低。官方推荐使用collections.deque
from collections import deque # 栈示例 stack = [1, 2, 3] stack.append(4) # 入栈 top = stack.pop() # 出栈,top = 4 # 队列示例 (使用deque) queue = deque(["Eric", "John", "Michael"]) queue.append("Terry") # 入队 first = queue.popleft() # 出队,first = 'Eric'
6.3 多维列表与嵌套

列表可以包含其他列表,形成多维结构,常用于表示矩阵或表格数据。

matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] # 访问元素 print(matrix[1](@ref) # 输出: 2 print(matrix[2](@ref) # 输出: 6 # 嵌套列表推导式转置矩阵 transposed = [[row[i] for row in matrix] for i in range(3)] print(transposed) # 输出: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
6.4 列表的比较

可以使用import operator模块的operator.eq()方法来比较两个列表是否完全相等。

import operator a = [1, 2] b = [2, 3] c = [2, 3] print(operator.eq(a,b)) # False print(operator.eq(c,b)) # True
6.5 列表的遍历与迭代

最常用和Pythonic的方式是使用for循环直接遍历元素。

fruits = ['apple', 'banana', 'cherry'] for fruit in fruits: print(fruit)

7. 列表推导式深入

列表推导式是Python中创建列表的优雅方式,它结合了mapfilter的功能,代码更简洁、易读。

7.1 基本语法与示例

[expression for item in iterable]

# 传统方式 squares = [] for x in range(10): squares.append(x**2) # 列表推导式 squares = [x**2 for x in range(10)]
7.2 带有条件筛选的推导式

[expression for item in iterable if condition]

even_squares = [x**2 for x in range(10) if x % 2 == 0] print(even_squares) # 输出: [0, 4, 16, 36, 64]
7.3 嵌套循环的推导式

[expression for item1 in iterable1 for item2 in iterable2]

# 将两个列表中不相等的元素组合成元组 pairs = [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y] print(pairs) # 输出: [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
7.4 复杂表达式与函数调用

推导式中的表达式可以很复杂,甚至调用函数。

from math import pi # 将圆周率四舍五入到不同小数位 pi_rounded = [str(round(pi, i)) for i in range(1, 6)] print(pi_rounded) # 输出: ['3.1', '3.14', '3.142', '3.1416', '3.14159']

8. 常用内置函数与列表的协同

8.1enumerate():同时获取索引和值

当你需要在循环中同时获得元素及其索引时,enumerate()是非常棒的选择。

fruits = ['apple', 'banana', 'cherry'] for index, fruit in enumerate(fruits): print(f"Index {index}: {fruit}") # 输出: # Index 0: apple # Index 1: banana # Index 2: cherry
8.2zip():并行迭代多个列表

zip()将多个可迭代对象打包成一个元组迭代器,可以方便地并行处理多个列表。

names = ['Alice', 'Bob', 'Charlie'] scores = [85, 92, 78] for name, score in zip(names, scores): print(f"{name}: {score}") # 输出: # Alice: 85 # Bob: 92 # Charlie: 78
8.3map()filter():函数式操作

map()将一个函数应用于一个可迭代对象的每个元素;filter()根据一个函数(返回布尔值)过滤一个可迭代对象。通常可以用列表推导式替代它们,但有时结合lambda函数使用也很方便。

numbers = [1, 2, 3, 4, 5] # map: 计算每个数的平方 squared = list(map(lambda x: x**2, numbers)) # [1, 4, 9, 16, 25] # filter: 筛选出奇数 odds = list(filter(lambda x: x % 2 != 0, numbers)) # [1, 3, 5]
8.4sorted():返回新排序列表

与列表的sort()方法不同,sorted()函数不会修改原列表,而是返回一个新的已排序列表

numbers = [3, 1, 2] sorted_numbers = sorted(numbers) print(numbers) # 输出: [3, 1, 2] (原列表不变) print(sorted_numbers) # 输出: [1, 2, 3] (新排序列表)
8.5reversed():返回反向迭代器

reversed()返回一个反向迭代器,你可以用list()将其转换为列表,或者直接用于循环。

numbers = [1, 2, 3] reversed_iter = reversed(numbers) for num in reversed_iter: print(num) # 输出: 3, 2, 1

9. 列表的局限性与替代方案

尽管列表非常强大,但在某些特定场景下存在局限性:

9.1 性能考量:何时使用数组 (array)

列表中的元素是Python对象,每个对象都有额外开销(对象头、引用计数等)。当存储大量同质的基本数据类型时,这会浪费大量内存并降低处理速度。

9.2 固定类型数据:array模块

Python的array模块提供了array类型,它像一个列表,但所有元素必须是同一类型。这使得它比列表更节省内存。例如,array('i', [1, 2, 3])创建一个整数数组。

9.3 数值计算:NumPy数组

对于科学计算、数据分析等重数值任务,NumPy数组是更好的选择。它支持ndarray(N维数组),不仅在内存中更紧凑,还提供了大量高效的矢量化运算(element-wise operations)和线性代数函数。例如,对NumPy数组进行a*2会直接对每个元素乘以2,而列表则需要列表推导式。


10. 最佳实践与常见陷阱

10.1 遍历时修改列表

在遍历列表时直接删除或插入元素会导致索引错乱和意想不到的bug。推荐的做法是创建一个新列表,或者遍历列表的副本。

错误示例:

numbers = [1, 2, 3, 4, 5] for num in numbers: if num % 2 == 0: numbers.remove(num) # 可能会跳过元素,或导致索引错误

正确做法:

# 创建新列表 numbers = [1, 2, 3, 4, 5] new_numbers = [num for num in numbers if num % 2 != 0] # 或者遍历副本 numbers = [1, 2, 3, 4, 5] for num in numbers[:]: # 遍历列表的切片副本 if num % 2 == 0: numbers.remove(num)
10.2 默认参数中使用可变对象

在函数定义中,默认参数只被求值一次。如果使用列表作为默认参数,多次调用该函数会共享同一个列表对象,导致意外结果。

陷阱示例:

def add_to_list(element, my_list=[]): my_list.append(element) return my_list print(add_to_list(1)) # 输出: print(add_to_list(2)) # 输出: [1, 2] 这不是预期的行为!

正确做法:

def add_to_list(element, my_list=None): if my_list is None: my_list = [] my_list.append(element) return my_list
10.3 列表的None返回值方法

append()sort()extend()reverse()等方法是原地修改列表,它们不返回新列表,而是返回None。新手常犯的错误是将返回值赋给变量,以为得到了新列表。

错误示例:

my_list = [3, 1, 2] sorted_list = my_list.sort() print(sorted_list) # 输出: None print(my_list) # 输出: [1, 2, 3](原列表被修改)

正确做法:

my_list = [3, 1, 2] my_list.sort() # 直接排序,不赋值 # 或者如果需要新列表,使用 sorted() 函数 sorted_list = sorted(my_list)

11. 总结与展望

Python列表是构建程序的基石,其灵活性、易用性和强大功能使其成为处理数据的首选工具。通过掌握其创建、访问、修改、切片、推导式、以及与其他内置函数的协同,你已经获得了高效编码的必备技能。同时,了解其局限性,并在合适的时候选择arrayNumPycollections.deque等替代方案,将使你的代码更加高效和专业。

http://www.jsqmd.com/news/842690/

相关文章:

  • SAP S/4HANA 2SL 中导入 Customizing Collection 的项目实战方法
  • FamiStudio音质优化与性能调优:确保流畅的音乐制作体验
  • EcoServe:LLM服务系统的资源调度优化实践
  • 2026年4月真空计销售商口碑推荐,真空计/氦质谱检漏仪/真空泵,真空计供应商哪家好 - 品牌推荐师
  • 日期时间数据在数据分析中的实际应用
  • 多模态桌面智能体完整实现指南:音频·文字·视频识别 + 桌面控制 + 自主点外卖
  • ClassiCube多平台适配技术:从桌面到移动再到游戏主机的实现细节
  • 如何轻松地将 iPhone 上的 Safari书签传输到电脑?
  • 移动计算指令预取优化:DEER架构解析与实践
  • vscode-mssql查询执行与结果分析:10个必备技能提升查询效率
  • 宁波亚克力板生产厂家推荐:2026亚克力展示架/亚克力板供应商排行top榜指南 - 栗子测评
  • 2026年亲测有效!学姐教你把论文AI率从90%降到10%(附降AIGC率工具) - 降AI实验室
  • 数据中台是什么?数据中台的架构设计有哪些?
  • 吴恩达提示词工程精华:从入门到精通,一篇搞定AI对话技巧
  • 面向低资源语言 Agent 的 Harness 回退翻译
  • 告别UUID!用Apache Commons Lang3的RandomStringUtils生成更灵活的随机字符串(Java实战)
  • GAS-ICS-Sync最佳实践:企业级日历同步解决方案终极指南
  • TVA智能体范式的工业视觉革命(6)
  • 上海亚卡黎实业有限公司2026高空作业平台设备精选:高空作业车采购优选厂家/品牌/生产厂家推荐上海亚卡黎实业 - 栗子测评
  • PCIe 4.0/5.0硬件设计必看:你的Rx EQ和Package如何影响压力眼图校准?
  • Animockup用户界面设计解析:现代化暗色主题与交互体验优化
  • 如何在 ECS 实例内部配置内网 SLB 监听实现负载均衡
  • 硬件产品开发实战:从可视化到可追溯的工程化框架
  • LISN:EMC测试中的“守门员”,如何精准捕获传导干扰?
  • NotebookLM权限最小化实践:如何用5行YAML实现文档级、片段级、引用源级三重访问控制(生产环境已验证)
  • 2026 年全国 PMP 培训行业发展现状与主流机构实力分析报告
  • 告别双系统!用WSL2+Ubuntu20.04+ROS Noetic玩转AirSim仿真(保姆级避坑指南)
  • 【Nginx】Nginx index 指令全解:从首页加载失败到高性能目录服务的生产实践
  • Google:让鼠标学会「看见」这件事意味着什么#Magic Pointer
  • 2026亚克力相框/盒子/尺子/收纳盒厂家哪家好?亚克力制品源头工厂推荐 - 栗子测评