第4章:操作列表(Working with Lists)
一、导读
1.1 本章学习目标
第4章深入讲解列表的高级操作。本章核心目标:
- 掌握for循环遍历列表:最基础的列表操作
- 熟练使用range()函数:生成数值序列
- 掌握列表推导式:Python最优雅的特性之一
- 学会数值列表的统计操作:min()、max()、sum()
- 理解元组的特性和用途:不可变的列表
- 掌握列表切片的实际应用:复制、替换、删除
1.2 为什么本章如此重要
for循环和列表推导式是Python编程中使用频率最高的操作模式。列表推导式尤其重要——它用一行代码就能完成传统循环需要多行代码才能实现的功能,而且更加Pythonic。
1.3 核心问题引导
列表推导式和for循环相比有什么优势和劣势?
range()函数在Python 2和Python 3中有什么区别?
元组不可变意味着什么?为什么需要不可变的数据结构?
列表推导式可以嵌套吗?嵌套后代码可读性如何?
二、核心概念详解
4.1 for循环遍历列表
python
# 基本遍历
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# 带索引遍历
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")
# 修改元素
numbers = [1, 2, 3, 4, 5]
for i in range(len(numbers)):
numbers[i] *= 2
print(numbers) # [2, 4, 6, 8, 10]
# 使用引用修改
for i in range(len(numbers)):
numbers[i] += 10
print(numbers) # [12, 14, 16, 18, 20]4.2 range()函数
python
# range(stop):0到stop-1
for i in range(5):
print(i) # 0, 1, 2, 3, 4
# range(start, stop):start到stop-1
for i in range(2, 8):
print(i) # 2, 3, 4, 5, 6, 7
# range(start, stop, step)
for i in range(0, 10, 2):
print(i) # 0, 2, 4, 6, 8
# 倒序
for i in range(10, 0, -1):
print(i) # 10, 9, 8, ..., 1
# range转列表
print(list(range(5))) # [0, 1, 2, 3, 4]
print(list(range(2, 10, 3))) # [2, 5, 8]4.3 列表推导式
列表推导式是Python最强大的特性之一:
python
# 基本形式:[expression for item in iterable]
squares = [x**2 for x in range(1, 11)]
print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 带条件过滤
evens = [x for x in range(1, 21) if x % 2 == 0]
print(evens) # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# 字符串处理
words = ["hello", "world", "python"]
upper_words = [word.upper() for word in words]
print(upper_words) # ['HELLO', 'WORLD', 'PYTHON']
# 嵌套推导
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [x for row in matrix for x in row]
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 字典推导式
word_lengths = {word: len(word) for word in words}
print(word_lengths) # {'hello': 5, 'world': 5, 'python': 6}
# 集合推导式
unique_lengths = {len(word) for word in words}
print(unique_lengths) # {5, 6}4.4 数值列表统计
python
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5]
print(f"Min: {min(numbers)}") # 1
print(f"Max: {max(numbers)}") # 9
print(f"Sum: {sum(numbers)}") # 36
print(f"Count: {len(numbers)}") # 9
print(f"Average: {sum(numbers) / len(numbers):.2f}") # 4.00
# 自定义统计
def statistics(data):
n = len(data)
mean = sum(data) / n
sorted_data = sorted(data)
median = sorted_data[n // 2] if n % 2 == 1 else \
(sorted_data[n // 2 - 1] + sorted_data[n // 2]) / 2
variance = sum((x - mean) ** 2 for x in data) / n
return {
'count': n,
'sum': sum(data),
'mean': mean,
'median': median,
'min': min(data),
'max': max(data),
'variance': variance
}
stats = statistics(numbers)
for key, value in stats.items():
print(f"{key}: {value:.2f}" if isinstance(value, float) else f"{key}: {value}")4.5 元组
python
# 元组是不可变的列表
dimensions = (1920, 1080)
print(dimensions[0]) # 1920
# dimensions[0] = 800 # TypeError: 不可修改
# 元组解包
width, height = dimensions
print(f"{width}x{height}")
# 单元素元组(注意逗号)
single = (42,)
print(type(single)) # <class 'tuple'>
# 元组交换
a, b = 1, 2
a, b = b, a # 交换
print(a, b) # 2, 1
# 函数返回多个值(实际返回元组)
def min_max(numbers):
return min(numbers), max(numbers)
lo, hi = min_max([3, 1, 4, 1, 5])
print(f"Min: {lo}, Max: {hi}")
# 命名元组
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(3, 4)
print(p.x, p.y) # 3 44.6 列表切片应用
python
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 复制列表
copy1 = numbers[:]
copy2 = numbers.copy()
import copy
copy3 = copy.deepcopy(numbers) # 深拷贝
# 替换子列表
numbers[2:5] = [20, 30, 40]
print(numbers)
# 删除子列表
numbers[2:5] = []
print(numbers)
# 在指定位置插入
numbers[2:2] = [100, 200]
print(numbers)
# 每隔n个取一个
every_other = numbers[::2]
print(every_other)
# 反转
reversed_list = numbers[::-1]
print(reversed_list)三、实战案例
4.1 数据分析小工具
python
import random
# 生成模拟数据
scores = [random.randint(50, 100) for _ in range(30)]
print("=== Score Analysis ===")
print(f"Scores: {scores}")
print(f"Count: {len(scores)}")
print(f"Average: {sum(scores) / len(scores):.1f}")
print(f"Highest: {max(scores)}")
print(f"Lowest: {min(scores)}")
# 分数段统计
bins = [(90, 100, 'A'), (80, 89, 'B'), (70, 79, 'C'), (60, 69, 'D'), (0, 59, 'F')]
print("\n=== Grade Distribution ===")
for low, high, grade in bins:
count = len([s for s in scores if low <= s <= high])
bar = "█" * count
print(f"{grade} ({low}-{high}): {bar} ({count})")
# 找出异常值
mean = sum(scores) / len(scores)
outliers = [s for s in scores if abs(s - mean) > 20]
print(f"\nOutliers: {outliers}")4.2 矩阵转置
python
# 使用列表推导式实现矩阵转置
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# 方法1:嵌套推导式
transposed = [[matrix[j][i] for j in range(len(matrix))]
for i in range(len(matrix[0]))]
print("Transposed:")
for row in transposed:
print(row)
# 方法2:zip
transposed2 = list(map(list, zip(*matrix)))
print("\nUsing zip:")
for row in transposed2:
print(row)四、本章小结
第4章深入讲解了列表的高级操作:
for循环:遍历列表的基本方式,配合enumerate获取索引。
range():生成数值序列,支持start、stop、step参数。
列表推导式:Python最优雅的特性之一,用一行代码完成列表创建和变换。
统计函数:min()、max()、sum()、len()用于数值列表的基本统计。
元组:不可变的列表,用于表示固定数据。支持解包。
切片应用:复制、替换、删除、反转等操作。
五、思考与练习
思考题
列表推导式和map/filter函数相比,哪个更Pythonic?
元组不可变有什么实际好处?什么时候应该用元组而不是列表?
嵌套列表推导式的执行顺序是什么?
numbers[:] 和 numbers.copy() 有什么区别?
编程练习
使用列表推导式生成九九乘法表。
编写程序,找出列表中所有出现超过一次的元素。
实现矩阵乘法(使用列表推导式)。