列表
变量只能保存一个东西。列表可以按顺序保存许多东西,全部归在一个名字下。排行榜是一串有序的分数。测验是一组题目的集合。一旦你需要管理一组相关的值,你就需要一个列表。
创建列表
使用方括号,值之间用逗号分隔。列表可以混合保存任何类型的值,空列表也是合法的,常作为逐步构建的起点。
scores = [87, 92, 74, 65, 91]
players = ["小明", "小红", "小刚"]
mixed = ["小明", 87, True, 3.14] # 任何类型,但不常见
empty = []索引和切片
列表使用与字符串相同的编号方式:位置从 0 开始,负数从末尾倒数。你可以按位置读取任何元素。因为列表是可变的,所以你也可以向特定位置写入。
scores = [87, 92, 74, 65, 91]
scores[0] # 87 (第一个)
scores[-1] # 91 (最后一个)
scores[1:3] # [92, 74]
scores[:2] # [87, 92]
scores[::-1] # [91, 65, 74, 92, 87] (反转)
scores[0] = 90 # 可变:可以工作(字符串会抛出 TypeError)添加元素
有三种添加元素的方法。append() 将单个元素添加到末尾,这是你几乎每次都会用的方法。insert() 在指定位置添加。extend() 合并另一个列表。
scores = [87, 92, 74]
scores.append(65) # [87, 92, 74, 65]
scores.insert(1, 100) # [87, 100, 92, 74, 65]
scores.extend([55, 71]) # [87, 100, 92, 74, 65, 55, 71]一个常见的错误:对一个列表使用 append() 会将整个列表作为一个元素添加,得到一个嵌套在列表中的列表。要合并,请使用 extend():
scores.append([55, 71]) # [..., [55, 71]] 嵌套列表,可能是错的
scores.extend([55, 71]) # [..., 55, 71] 合并,正确删除元素
有四种工具可以删除元素。remove() 按值搜索。pop() 按位置删除,并返回该元素。del 按位置删除,但不返回值。clear() 清空整个列表。
scores = [87, 92, 74, 65, 91]
scores.remove(74) # 删除第一次出现的 74
scores.pop() # 删除并返回最后一项 (91)
scores.pop(0) # 删除并返回位置 0 的元素 (87)
del scores[1] # 删除位置 1 的元素,无返回值
scores.clear() # 删除所有元素如果值不在列表中,remove() 会抛出 ValueError。如果不确定,可以先用 in 检查:
if 74 in scores:
scores.remove(74)排序
sorted() 返回一个全新的已排序列表,原列表保持不变。.sort() 就地排序并返回 None。这个差别比听起来更重要。
scores = [87, 42, 96, 55, 71]
ranked = sorted(scores) # [42, 55, 71, 87, 96] (新列表)
scores.sort() # 就地排序,返回 None
scores.sort(reverse=True) # [96, 87, 71, 55, 42]
result = scores.sort() # result 是 None,不是排序后的列表常用操作
Python 有一组直接作用于列表的内置工具。len()、sum()、min() 和 max() 是你会经常用到的四个。
scores = [87, 92, 74, 65, 91]
len(scores) # 5
sum(scores) # 409
min(scores) # 65
max(scores) # 92
scores.count(87) # 1
scores.index(74) # 2
74 in scores # True
74 not in scores # False
scores.copy() # 浅拷贝
scores.reverse() # 就地反转迭代
for 循环会一次一个地遍历列表。for 后面的变量依次接收每个元素。当你还需要位置时,enumerate() 可以同时给你两者,而无需手动计数。
players = ["小明", "小红", "小刚"]
for player in players:
print(player)
for i, player in enumerate(players, start=1):
print(f"{i}. {player}")
# 1. 小明
# 2. 小红
# 3. 小刚for 循环和 enumerate
for 和 enumerate() 将在 控制流 章节完整介绍。简短版本:for player in players 每个元素运行一次;enumerate() 在每次迭代中同时给你位置和值。
嵌套列表
列表可以包含其他列表。这就是表示网格或表格的方式:一个行的列表,每行是一个值的列表。两组方括号访问一个元素:第一组选择行,第二组选择列。
grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
grid[0] # [1, 2, 3]
grid[1][2] # 6 (第 1 行,第 2 列)可变性:陷阱所在
这几乎让每个人都吃过亏。将列表赋给一个新变量并不会创建副本。两个名字指向同一个列表。改一个就改了另一个。要得到独立的副本,你必须显式请求。
a = [1, 2, 3]
b = a # b 不是副本;它指向同一个列表
b.append(4)
print(a) # [1, 2, 3, 4] (变了:a 和 b 是同一个列表)b = a.copy() # 独立的副本
b = list(a) # 同样的结果
b = a[:] # 也一样
# 嵌套列表的内部对象仍然是共享的:
matrix = [[1, 2], [3, 4]]
copy = matrix.copy()
copy[0].append(99)
print(matrix) # [[1, 2, 99], [3, 4]] (内部列表是共享的)更多方法
| 方法 | 作用 |
|---|---|
.append(item) | 添加到末尾 |
.insert(i, item) | 在位置 i 插入 |
.extend(iterable) | 从可迭代对象添加所有元素 |
.remove(value) | 删除第一次出现的值 |
.pop(i) | 删除并返回位置 i 的元素(默认:最后一个) |
.clear() | 删除所有元素 |
.index(value) | 第一次出现的位置 |
.count(value) | 出现的次数 |
.sort() | 就地排序 |
.reverse() | 就地反转 |
.copy() | 返回浅拷贝 |
实战
构建一个分数跟踪器:添加结果、排序,并打印摘要。
scores = []
scores.append(87)
scores.append(54)
scores.append(92)
scores.append(67)
scores.append(45)
scores.sort(reverse=True)
print(f"排名分数: {scores}")
print(f"最高: {scores[0]}")
print(f"最低: {scores[-1]}")
print(f"平均: {sum(scores) / len(scores):.1f}")
print(f"前 3 名: {scores[:3]}")
