【Python】列表
列表
列表基本概念
列表是 Python 中的内置数据类型之一。Python 列表是一系列逗号分隔的项目,用方括号括起来[ ]。Python 列表中的项目不需要是相同的数据类型。
以下是 Python 列表的一些示例-
list1 = ["Rohan", "Physics", 21, 69.75]
list2 = [1, 2, 3, 4, 5]
list3 = ["a", "b", "c", "d"]
list4 = [25.50, True, -55, 1+2j]
列表是有序的项目集合。列表中的每个项目都有一个唯一的位置索引,从 0 开始。
Python 中的列表类似于 C、C++ 或 Java 中的数组。然而,主要区别在于,在 C/C++/Java 中,数组元素必须是相同的类型。另一方面,Python 列表可能包含不同数据类型的对象。
Python列表是可变的。列表中的任何项目都可以使用其索引访问,并且可以进行修改。可以从列表中删除或添加一个或多个对象。一个列表可能在多个索引位置有相同的项目。
列表推导式
什么是列表推导式?
- 定义:列表推导式(List Comprehension)是一种简洁的语法,用一行代码基于 可迭代对象(如 list、str、range 等)生成新的列表。
- 本质:语法糖,相当于把
for循环 + 条件判断 +append浓缩到一行里。 - 语法:
[expression for item in iterable if condition]
组成部分:
expression:对每个元素要执行的操作(表达式)item:循环变量iterable:可迭代对象(列表、字符串、元组等)condition:过滤条件(可选)
生成简单列表
nums = [x for x in range(5)]
print(nums) # [0, 1, 2, 3, 4]
带条件过滤
even = [x for x in range(10) if x % 2 == 0]
print(even) # [0, 2, 4, 6, 8]
带计算公式
squares = [x**2 for x in range(5)]
print(squares) # [0, 1, 4, 9, 16]
使用函数
def square(x): return x * x
nums = [square(x) for x in range(5)]
print(nums) # [0, 1, 4, 9, 16]
与 Lambda 结合
original = [1, 2, 3, 4, 5]
doubled = [(lambda x: x * 2)(x) for x in original]
print(doubled) # [2, 4, 6, 8, 10]
多层循环(笛卡尔积)
pairs = [(x, y) for x in [1, 2, 3] for y in ['a', 'b']]
print(pairs) # [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b')]
条件表达式(三元运算符)
result = ["even" if x % 2 == 0 else "odd" for x in range(5)]
print(result) # ['even', 'odd', 'even', 'odd', 'even']
扁平化嵌套列表
matrix = [[1,2,3], [4,5,6], [7,8,9]]
flat = [num for row in matrix for num in row]
print(flat) # [1,2,3,4,5,6,7,8,9]
与传统循环对比
普通写法
squares = []
for x in range(5):
if x % 2 == 0:
squares.append(x**2)
列表推导式写法
squares = [x**2 for x in range(5) if x % 2 == 0]
更简洁、性能更好。
独立作用域(Python 3)
x = 100
lst = [x for x in range(3)]
print(x) # 100 不受影响
性能
- 比普通
for + append快 1.5~2 倍。 - 但过度复杂的推导式会降低可读性。
访问列表项
在 Python 中,列表是元素或对象的序列,即有序的对象集合。与数组类似,列表中的每个元素都对应一个索引。
要访问列表中的值,我们需要使用方括号**“[]”**符号,并指定要检索的元素的索引。
第一个元素的索引从 0 开始,每个后续元素的索引都以 1 为单位。列表中最后一个项目的索引总是“长度-1”,其中“长度”表示列表中项目的总数。
除此之外,Python 还提供了各种访问列表项的方法,如切片、负索引、从列表中提取子列表等。
基础:索引(Indexing)
列表是有序序列,每个元素都对应一个 索引号。
- 正索引:从
0到len(lst)-1。 - 负索引:从
-1(最后一个)到-len(lst)(第一个)。 - 超出范围:
IndexError: list index out of range。
lst = ["Rohan", "Physics", 21, 69.75]
print(lst[0]) # Rohan
print(lst[2]) # 21
print(lst[-1]) # 69.75
负索引(从末尾反向访问)
负数索引更直观地表示“从后往前”。
nums = [25.50, True, -55, 1+2j]
print(nums[-1]) # (1+2j)
print(nums[-3]) # True
切片(Slicing)
语法:lst[start:stop:step]
特点:
- 包含 start,不包含 stop(左闭右开区间)。
- 返回的是 新列表(浅拷贝)。
- 索引省略时有默认值:
[:stop]= 从头到 stop-1[start:]= 从 start 到结尾[:]= 全部(拷贝)
lst = ["a", "b", "c", "d"]
print(lst[1:]) # ['b', 'c', 'd']
print(lst[:2]) # ['a', 'b']
print(lst[:]) # ['a', 'b', 'c', 'd']
print(lst[::-1]) # ['d', 'c', 'b', 'a'] 反转
print(lst[::2]) # ['a', 'c'] 隔一个取一个
子列表(Sublist)
通过切片获取列表的一部分,形成“子列表”:
lst = ["a", "b", "c", "d"]
print(lst[1:3]) # ['b', 'c'],索引 1 和 2
切片超出范围时不会报错:
print(lst[2:100]) # ['c', 'd']
print(lst[100:200]) # []
查找元素的位置
in:检查是否存在index():找出位置,找不到抛错count():统计出现次数
lst = [10, 20, 30, 20]
print(20 in lst) # True
print(lst.index(20)) # 1
print(lst.index(20, 2))# 3
print(lst.count(20)) # 2
嵌套列表访问
二维或多维列表用链式索引:
mat = [[1,2,3],[4,5,6],[7,8,9]]
print(mat[0][1]) # 2
print(mat[2][2]) # 9
遍历时访问索引和值
常用 enumerate 和 zip。
lst = ['a','b','c']
for i, val in enumerate(lst):
print(i, val)
a = [1,2,3]
b = ['x','y','z']
for x, y in zip(a, b):
print(x, y)
按多个索引批量取值
lst = [10,20,30,40,50]
indices = [0,2,4]
# 列表推导式
result = [lst[i] for i in indices] # [10,30,50]
# itemgetter
from operator import itemgetter
getter = itemgetter(0,2,4)
print(getter(lst)) # (10,30,50)
更改列表项
Python 的 列表(list) 是一种 可变数据类型(mutable)。这意味着,在列表对象创建后,你可以直接修改它的内容,而不需要创建新列表。
修改操作主要通过 索引、切片、循环、推导式 等方式完成。
基本修改(通过索引)
最基础的方式就是使用索引来替换某个位置的元素。
语法:
list1[i] = new_value
示例:
list3 = [1, 2, 3, 4, 5]
print("Original list:", list3)
list3[2] = 10 # 修改索引 2 的元素
print("List after change:", list3)
输出:
Original list: [1, 2, 3, 4, 5]
List after change: [1, 2, 10, 4, 5]
要点:
- 索引从
0开始。 list[index]必须在有效范围内,否则会报错IndexError。
使用负索引修改
Python 支持 负索引,可以从右往左数。
示例:
nums = [10, 20, 30, 40]
nums[-1] = 99 # 修改最后一个元素
nums[-3] = 111 # 修改倒数第三个元素
print(nums)
输出:
[10, 111, 30, 99]
修改连续的列表项(切片)
切片不仅可以读取子列表,还能替换 多个连续的元素。
-
替换为等长子列表
list1 = ["a", "b", "c", "d"] list1[1:3] = ["X", "Y"] # 用 2 个元素替换 b 和 c print(list1)输出:
['a', 'X', 'Y', 'd'] -
替换为更长的子列表(扩展列表)
list1 = ["a", "b", "c", "d"] list1[1:3] = ["X", "Y", "Z"] # 替换 b,c,并插入额外的元素 Z print(list1)输出:
['a', 'X', 'Y', 'Z', 'd'] -
替换为更短的子列表(缩减列表)
list1 = ["a", "b", "c", "d"] list1[1:3] = ["Z"] # 用 1 个元素替换 b,c print(list1)输出:
['a', 'Z', 'd']
使用切片修改多个非连续元素(步长切片)
切片还能带步长,用于修改间隔位置的元素。
示例:
nums = [0, 1, 2, 3, 4, 5, 6]
nums[::2] = [10, 20, 30, 40] # 步长=2,修改偶数索引位置
print(nums)
输出:
[10, 1, 20, 3, 30, 5, 40]
注意:替换的子列表必须和切片长度一致,否则报 ValueError。
批量修改(循环)
如果想根据规则批量修改,可以用 循环。
nums = [1, 2, 3, 4, 5]
for i in range(len(nums)):
nums[i] = nums[i] * 2 # 所有元素乘 2
print(nums)
输出:
[2, 4, 6, 8, 10]
批量修改(循环)
如果想根据规则批量修改,可以用 循环。
nums = [1, 2, 3, 4, 5]
for i in range(len(nums)):
nums[i] = nums[i] * 2 # 所有元素乘 2
print(nums)
输出:
[2, 4, 6, 8, 10]
使用列表推导式生成新列表
虽然这会创建一个新列表,但在实际开发中经常作为“修改”的一种方式。
nums = [1, 2, 3, 4, 5]
nums = [x**2 for x in nums] # 所有元素平方
print(nums)
输出:
[1, 4, 9, 16, 25]
原表修改 vs 新建列表
list[i] = value→ 直接修改原列表(影响原数据)。- 列表推导式 → 创建新列表,不会修改原列表,适合保持数据安全。
添加列表项
在 Python 中,列表(list)是可变对象,创建后可以修改:包括 添加、删除、修改 元素。
“添加列表项”就是在现有列表中插入新元素,常见方式有:
- 在 末尾 添加 →
append() - 在 指定位置 插入 →
insert() - 在 末尾批量扩展 →
extend()
使用 append() —— 在末尾添加单个元素
这是最常用的方法。
语法
list.append(item)
item:要添加的新元素,可以是数字、字符串、列表,甚至对象。
示例
list1 = ["a", "b", "c", "d"]
print("Original list:", list1)
list1.append("e")
print("List after appending:", list1)
输出:
Original list: ['a', 'b', 'c', 'd']
List after appending: ['a', 'b', 'c', 'd', 'e']
注意:如果 append() 的参数本身是列表,它会作为一个整体添加进去:
nums = [1, 2, 3]
nums.append([4, 5])
print(nums) # [1, 2, 3, [4, 5]]
使用 insert() —— 在指定位置插入元素
适合需要精确控制位置时。
语法
list.insert(index, item)
index:插入位置(0-based,支持负数,插入到索引index的位置之前)。item:要插入的元素。
示例
list1 = ["Rohan", "Physics", 21, 69.75]
list1.insert(2, "Chemistry")
print(list1)
# ['Rohan', 'Physics', 'Chemistry', 21, 69.75]
list1.insert(-1, "Pass")
print(list1)
# ['Rohan', 'Physics', 'Chemistry', 21, 'Pass', 69.75]
注意:负索引在插入时不会“动态更新”,它是按插入前的索引计算的。
使用 extend() —— 批量添加多个元素
与 append() 不同,extend() 会把传入的可迭代对象 拆开逐一添加。
语法
list.extend(iterable)
示例
list1 = [1, 2, 3]
another_list = [4, 5, 6]
list1.extend(another_list)
print("Extended list:", list1)
# [1, 2, 3, 4, 5, 6]
list1.extend("ab")
print(list1)
# [1, 2, 3, 4, 5, 6, 'a', 'b']
对比:
nums = [1, 2, 3]
nums.append([4, 5])
print(nums) # [1, 2, 3, [4, 5]]
nums = [1, 2, 3]
nums.extend([4, 5])
print(nums) # [1, 2, 3, 4, 5]
切片赋值 —— 在任意位置批量插入
除了 insert(),切片赋值也能插入多个元素。
示例
nums = [1, 4, 5]
nums[1:1] = [2, 3] # 在索引 1 前插入
print(nums) # [1, 2, 3, 4, 5]
nums[len(nums):] = [6, 7] # 在末尾追加
print(nums) # [1, 2, 3, 4, 5, 6, 7]
使用 + 运算符 —— 拼接生成新列表
不会修改原列表,而是返回一个新列表。
a = [1, 2]
b = [3, 4]
c = a + b
print(c) # [1, 2, 3, 4]
print(a) # [1, 2] (原列表没变)
使用列表推导式 / 循环 —— 自定义添加逻辑
nums = [1, 2, 3]
new_items = [x**2 for x in nums] # 列表推导式
nums.extend(new_items)
print(nums) # [1, 2, 3, 1, 4, 9]
使用 * 运算符 —— 重复扩展
快速构造重复数据。
zeros = [0] * 5
print(zeros) # [0, 0, 0, 0, 0]
nums = [1, 2] * 3
print(nums) # [1, 2, 1, 2, 1, 2]
高级:用 collections.deque 高效添加
deque(双端队列)在两端插入更高效。
from collections import deque
dq = deque([1, 2, 3])
dq.append(4) # 右侧添加
dq.appendleft(0) # 左侧添加
print(dq) # deque([0, 1, 2, 3, 4])
方法对比表
| 方法 | 修改原列表 | 位置控制 | 批量支持 | 返回值 | 适用场景 |
|---|---|---|---|---|---|
append() |
✅ | 末尾 | ❌ | None | 单个元素追加 |
insert() |
✅ | 任意索引 | ❌ | None | 精确插入 |
extend() |
✅ | 末尾 | ✅ | None | 批量追加 |
+ 运算符 |
❌ | 末尾拼接 | ✅ | 新列表 | 保持原列表不变 |
| 切片赋值 | ✅ | 任意位置 | ✅ | None | 批量插入 |
| 推导式 | ❌ | 生成新列表 | ✅ | 新列表 | 批量生成逻辑 |
* 运算符 |
❌ | 重复扩展 | ✅ | 新列表 | 快速初始化 |
deque |
✅ | 两端 | ✅ | 队列对象 | 高效头部操作 |
删除列表项
在 Python 中,删除列表项意味着从现有列表中移除某些元素。因为列表是有序且可变的容器,所以我们既可以删除单个元素,也可以一次删除多个元素,甚至清空整个列表。
Python 提供了多种方式删除列表项,每种方法都有特点和适用场景。
使用 remove() —— 按值删除
- 删除 第一次出现的值。
- 如果值不存在,会报
ValueError。
list1 = ["Rohan", "Physics", 21, 69.75]
print("Original list:", list1)
list1.remove("Physics")
print("List after removing:", list1)
输出:
Original list: ['Rohan', 'Physics', 21, 69.75]
List after removing: ['Rohan', 21, 69.75]
注意:如果 "Physics" 出现多次,只会删除第一个。要删除所有,可以用 for 循环或推导式:
// for循环
list = ["a", "b", "c", "b", "d"]
for x in list:
if x == "b":
list.remove(x)
print(list) # ['a', 'c', 'd']
// 推导式
list1 = ["a", "b", "c", "b", "d"]
list1 = [x for x in list1 if x != "b"]
print(list1) # ['a', 'c', 'd']
使用 pop() —— 按索引删除(并返回值)
- 默认
pop()删除并返回最后一个元素。 - 可以传入索引
pop(i)删除并返回第i个元素。 - 如果索引越界,报
IndexError。
list2 = [25.50, True, -55, 1+2j]
print("Original list:", list2)
x = list2.pop(2) # 删除索引 2 处的 -55
print("Deleted elements:", x)
print("List after popping:", list2)
输出:
Original list: [25.5, True, -55, (1+2j)]
Deleted elements: -55
List after popping: [25.5, True, (1+2j)]
适合需要 获取被删除的值 的情况。
使用 clear() —— 清空整个列表
- 删除所有元素,变成一个空列表。
my_list = [1, 2, 3, 4, 5]
my_list.clear()
print("Cleared list:", my_list)
输出:
Cleared list: []
等价于:
my_list[:] = []
del my_list[:]
使用 del 关键字 —— 删除索引或切片
del list[i]→ 删除索引i处的元素。del list[start:stop]→ 删除一段范围。- 还可以直接
del list删除整个变量。
list1 = ["a", "b", "c", "d"]
print("Original list:", list1)
del list1[2] # 删除索引 2 的元素 "c"
print("List after deleting:", list1)
输出:
Original list: ['a', 'b', 'c', 'd']
List after deleting: ['a', 'b', 'd']
再看一个切片示例:
list2 = [25.50, True, -55, 1+2j]
print("List before deleting:", list2)
del list2[0:2] # 删除前两个元素
print("List after deleting:", list2)
输出:
List before deleting: [25.5, True, -55, (1+2j)]
List after deleting: [-55, (1+2j)]
高级技巧:按条件删除(推导式 / filter)
当你想根据条件删除多个元素时,可以用推导式:
例1:删除所有偶数
nums = [1, 2, 3, 4, 5, 6]
nums = [n for n in nums if n % 2 != 0]
print(nums) # [1, 3, 5]
例2:删除所有 None
data = [1, None, 2, None, 3]
data = list(filter(lambda x: x is not None, data))
print(data) # [1, 2, 3]
对比总结表
| 方法 | 按值 | 按索引 | 返回值 | 范围删除 | 清空 | 批量条件删除 |
|---|---|---|---|---|---|---|
remove() |
✅(只删第一个) | ❌ | ❌ | ❌ | ❌ | ❌ |
pop() |
❌ | ✅ | ✅(返回值) | ❌ | ❌ | ❌ |
clear() |
❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
del |
❌ | ✅ | ❌ | ✅(切片) | ✅(del list[:]) | ❌ |
| 推导式/filter | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ |
循环列表
在 Python 中,循环浏览列表项(Looping through list items)就是 逐个迭代列表中的元素,并对它们执行操作。这是 Python 中最常见的编程模式之一。
应用场景非常广,比如:
- 数据处理:批量修改元素、筛选数据
- 字符串操作:格式化输出、文本清洗
- 条件判断:找最大值、过滤符合条件的值
- 数据分析:统计、转换
Python 提供了多种方式来循环列表,从最常见的 for 到更高级的 enumerate、推导式,甚至 itertools 无限循环。
使用 for 循环
最常见方式:
lst = [25, 12, 10, -21, 10, 100]
for num in lst:
print(num, end=' ')
输出:
25 12 10 -21 10 100
场景:逐一读取元素即可,不关心索引。
使用 while 循环
用索引来控制迭代:
my_list = [1, 2, 3, 4, 5]
index = 0
while index < len(my_list):
print(my_list[index])
index += 1
输出:
1
2
3
4
5
场景:当需要手动控制循环(比如跳过、回退)时。
使用索引 range(len(list))
lst = [25, 12, 10, -21, 10, 100]
for i in range(len(lst)):
print(f"lst[{i}]: {lst[i]}")
输出:
lst[0]: 25
lst[1]: 12
lst[2]: 10
lst[3]: -21
lst[4]: 10
lst[5]: 100
场景:既要元素,又要索引,但不用 enumerate。
使用 enumerate() —— 索引+元素一起拿
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print(index, fruit)
输出:
0 apple
1 banana
2 cherry
推荐:这是最 Pythonic 的写法。
使用列表推导式(List Comprehension)
简洁表达式 + 遍历:
numbers = [1, 2, 3, 4, 5]
squared_numbers = [num ** 2 for num in numbers]
print(squared_numbers)
输出:
[1, 4, 9, 16, 25]
场景:遍历+生成新列表,特别适合数据处理。
同时循环多个列表 → zip()
names = ["Alice", "Bob", "Charlie"]
scores = [85, 90, 78]
for name, score in zip(names, scores):
print(f"{name} scored {score}")
输出:
Alice scored 85
Bob scored 90
Charlie scored 78
无限循环列表 → itertools.cycle
import itertools
colors = ["red", "green", "blue"]
for i, c in enumerate(itertools.cycle(colors)):
if i == 6: # 控制循环次数
break
print(c)
输出:
red
green
blue
red
green
blue
总结对比表
| 方法 | 是否可取索引 | 是否可改元素 | 特点 |
|---|---|---|---|
for item in list |
❌ | ❌ | 最常见,简单 |
while + index |
✅ | ✅ | 手动控制,更灵活 |
range(len(list)) |
✅ | ✅ | 传统写法 |
enumerate(list) |
✅ | ✅ | Pythonic,推荐 |
zip(list1, list2) |
✅(同时多个) | ✅ | 同时遍历多个列表 |
| 列表推导式 | ❌ | ✅(新列表) | 简洁,推荐 |
itertools.cycle() |
❌ | ❌ | 无限循环 |
| 推导式筛选 | ❌ | ✅ | 遍历时安全删除 |
排序列表
在 Python 中,排序(Sorting)是对列表(或其他可迭代对象)中的元素进行重新排列的过程,通常是 升序 或 降序。
Python 提供了两种主要方式来实现排序:
list.sort()方法 → 就地排序(修改原始列表,不返回新列表)sorted()内置函数 → 返回一个新的已排序列表(原列表保持不变)
使用 list.sort() 方法排序
语法
list_name.sort(key=None, reverse=False)
key:可选,自定义排序规则(函数),默认为自然顺序reverse:布尔值,False升序(默认),True降序- 不会返回新列表,而是直接修改原始列表
字母顺序
list1 = ['physics', 'Biology', 'chemistry', 'maths']
print("Before:", list1)
list1.sort()
print("After :", list1)
输出:
Before: ['physics', 'Biology', 'chemistry', 'maths']
After : ['Biology', 'chemistry', 'maths', 'physics']
数字顺序
list2 = [10, 16, 9, 24, 5]
list2.sort()
print(list2) # [5, 9, 10, 16, 24]
降序
nums = [5, 2, 9, 1]
nums.sort(reverse=True)
print(nums) # [9, 5, 2, 1]
使用 sorted() 函数排序
语法
sorted(iterable, key=None, reverse=False)
iterable:任何可迭代对象(列表、元组、字符串等)key:自定义排序规则reverse:是否降序- 返回新列表,原始序列不变
对列表排序(保留原始列表)
numbers = [3, 1, 4, 1, 5, 9]
sorted_numbers = sorted(numbers)
print(sorted_numbers) # [1, 1, 3, 4, 5, 9]
print(numbers) # [3, 1, 4, 1, 5, 9]
降序排序
numbers = [3, 1, 4, 1, 5, 9]
sorted_desc = sorted(numbers, reverse=True)
print(sorted_desc) # [9, 5, 4, 3, 1, 1]
使用 key 参数进行自定义排序
排序不仅仅是数字大小或字母顺序,你可以通过 key 传入函数定义规则。
忽略大小写
list1 = ['Physics', 'biology', 'Biomechanics', 'psychology']
list1.sort(key=str.lower)
print(list1)
# ['biology', 'Biomechanics', 'Physics', 'psychology']
根据字符串长度排序
words = ["apple", "banana", "pear", "kiwi"]
words.sort(key=len)
print(words) # ['kiwi', 'pear', 'apple', 'banana']
自定义函数排序(个位数大小)
def myfunction(x):
return x % 10
list1 = [17, 23, 46, 51, 90]
list1.sort(key=myfunction)
print(list1)
# [90, 51, 23, 46, 17] (个位数:0 < 1 < 3 < 6 < 7)
多条件排序
有时候你需要 先按一个条件,再按另一个条件。
可以用 元组 (key1, key2) 来实现。
students = [("Alice", 20), ("Bob", 20), ("Charlie", 18)]
students.sort(key=lambda x: (x[1], x[0])) # 先按年龄,再按名字
print(students)
# [('Charlie', 18), ('Alice', 20), ('Bob', 20)]
Python 的排序是 稳定排序(Stable Sort)
即:如果两个元素相等,它们的相对顺序不会改变。
data = [("apple", 2), ("banana", 2), ("cherry", 1)]
data.sort(key=lambda x: x[1])
print(data)
# [('cherry', 1), ('apple', 2), ('banana', 2)]
"apple" 和 "banana" 相对顺序保持不变。
复制列表
在 Python 中,复制列表 就是创建一个新的列表对象,它包含与原始列表相同的元素。
注意:直接用 b = a 不是复制,而是引用。修改 b 会影响 a,因为它们指向同一块内存。
列表复制的两大类
- 浅拷贝(Shallow Copy):浅拷贝创建了一个新对象没有递归地复制元素,而是只复制对原始元素的引用,新列表和原列表共享内部可变对象。
- 深拷贝(Deep Copy):深度副本创建一个全新的对象,并递归复制原始对象引用的所有对象,新列表完全独立。
浅拷贝的方法
-
切片符号
[:]original_list = [1, 2, 3, 4, 5] copied_list = original_list[:] # 全切片 copied_list[0] = 100 print("Original:", original_list) # [1, 2, 3, 4, 5] print("Copied:", copied_list) # [100, 2, 3, 4, 5]优点:常用、快速、简洁
缺点:对嵌套列表还是会共享引用切片
[:]或list[start:end]创建了一个 新的列表对象,所以修改复制列表的顶层元素不会影响原列表。但这只适用于列表元素是 不可变类型(如整数、字符串、元组)时,修改元素看起来就像深拷贝一样。
如果列表元素是 可变类型(如子列表、字典),修改内部对象会影响原列表,这就是浅拷贝的特征。
情况 1:元素不可变(整数、字符串)
original = [1, 2, 3] copy_list = original[:] copy_list[0] = 100 print("Original:", original) # [1, 2, 3] print("Copy:", copy_list) # [100, 2, 3]修改复制列表的元素不会影响原列表,看起来像深拷贝。
情况 2:元素可变(子列表)
original = [[1, 2], [3, 4]] copy_list = original[:] copy_list[0][0] = 99 print("Original:", original) # [[99, 2], [3, 4]] print("Copy:", copy_list) # [[99, 2], [3, 4]]修改复制列表的子列表会影响原列表,这就是浅拷贝。
-
list()构造函数original_list = [1, 2, 3, 4, 5] copied_list = list(original_list) print(copied_list) # [1, 2, 3, 4, 5] -
copy()方法(Python 3.3+)original_list = [1, 2, 3, 4, 5] copied_list = original_list.copy() print(copied_list) # [1, 2, 3, 4, 5] -
copy.copy()(标准库)import copy original_list = [[1, 2, 3], [4, 5, 6]] shallow_copied_list = copy.copy(original_list) shallow_copied_list[0][0] = 100 print("Original:", original_list) # [[100, 2, 3], [4, 5, 6]] print("Shallow Copied:", shallow_copied_list) # [[100, 2, 3], [4, 5, 6]]可以看到:浅拷贝只复制外层,内部元素还是共享的。
深拷贝的方法
方法:copy.deepcopy()
import copy
original_list = [[1, 2, 3], [4, 5, 6]]
deep_copied_list = copy.deepcopy(original_list)
deep_copied_list[0][0] = 100
print("Original:", original_list) # [[1, 2, 3], [4, 5, 6]]
print("Deep Copied:", deep_copied_list) # [[100, 2, 3], [4, 5, 6]]
递归复制所有嵌套对象,两个列表完全独立。
速度比浅拷贝慢,占用更多内存。
复制的对比总结
| 方法 | 类型 | 是否独立 | 适合场景 |
|---|---|---|---|
b = a |
引用 | 否 | 想让两个变量指向同一对象 |
a[:] |
浅拷贝 | 外层独立,内层共享 | 快速复制一层列表 |
list(a) |
浅拷贝 | 外层独立,内层共享 | 通用复制 |
a.copy() |
浅拷贝 | 外层独立,内层共享 | Python 3 常用 |
copy.copy(a) |
浅拷贝 | 外层独立,内层共享 | 用于一般对象 |
copy.deepcopy(a) |
深拷贝 | 完全独立 | 嵌套对象、复杂结构 |
列表方法
列表(List) 是 Python 中的基础数据结构之一,用于存储一系列有序元素。
列表可以包含不同类型的元素,包括数字、字符串、布尔值,甚至其他列表(嵌套列表)。
列表是可变对象(Mutable),可以动态修改其元素。
Python 提供了丰富的内置方法,让你可以高效地添加、删除、查找、排序、复制列表元素。
查看列表所有方法
可以使用 Python 的 dir() 函数查看列表的所有方法:
print(dir([]))
常用的方法包括:
append, clear, copy, count, extend, index, insert, pop, remove, reverse, sort
可以使用 help([]方法名) 查看详细用法,例如:
print(help([].append))
添加元素的方法
| 方法 | 功能 | 示例 |
|---|---|---|
append(obj) |
在列表末尾添加一个元素 | lst.append(5) |
extend(seq) |
将可迭代对象中的元素逐一添加到列表末尾 | lst.extend([6,7]) |
insert(index, obj) |
在指定索引位置插入元素,其后的元素整体后移 | lst.insert(1, 'x') |
示例:
lst = [1, 2, 3]
lst.append(4)
print(lst) # [1,2,3,4]
lst.extend([5,6])
print(lst) # [1,2,3,4,5,6]
lst.insert(1,'x')
print(lst) # [1,'x',2,3,4,5,6]
删除元素的方法
| 方法 | 功能 | 示例 |
|---|---|---|
clear() |
清空列表所有元素 | lst.clear() |
pop([index]) |
删除并返回指定索引元素,默认删除最后一个 | lst.pop() |
remove(obj) |
删除列表中第一个匹配的元素 | lst.remove(3) |
示例:
lst = [1, 2, 3, 4, 2]
lst.pop() # 删除最后一个元素
print(lst) # [1,2,3,4]
lst.pop(1) # 删除索引1的元素
print(lst) # [1,3,4]
lst.remove(3) # 删除第一个3
print(lst) # [1,4]
lst.clear() # 清空列表
print(lst) # []
访问列表元素的方法
| 方法 | 功能 | 示例 |
|---|---|---|
index(obj, start=0, end=len(list)) |
返回元素第一次出现的索引 | lst.index(2) |
count(obj) |
返回元素在列表中出现的次数 | lst.count(2) |
示例:
lst = ['a','b','c','b']
print(lst.index('b')) # 1
print(lst.index('b', 2, 4)) # 3
print(lst.count('b')) # 2
复制与排序方法
| 方法 | 功能 | 示例 |
|---|---|---|
copy() |
返回列表的浅拷贝 | lst2 = lst.copy() |
sort(key=None, reverse=False) |
就地排序,默认升序 | lst.sort() |
reverse() |
就地反转列表 | lst.reverse() |
示例:
lst = [3,1,2]
lst.sort()
print(lst) # [1,2,3]
lst.reverse()
print(lst) # [3,2,1]
lst2 = lst.copy()
lst2.append(4)
print(lst) # [3,2,1]
print(lst2) # [3,2,1,4]
- 高级用法:自定义排序
lst = ['apple','Banana','pear']
lst.sort(key=str.lower) # 忽略大小写排序
print(lst) # ['apple','Banana','pear']
内置函数和操作
len(lst)→ 获取列表长度x in lst→ 检查元素是否存在x not in lst→ 检查元素是否不存在lst1 + lst2→ 拼接列表lst1 += lst2→ 就地添加- 切片复制:
lst2 = lst[:] - 列表推导式:
lst2 = [x*2 for x in lst]
更多推荐


所有评论(0)