4Python编程:从入门到实践(第3版)

操作列表

列表的高级操作

遍历列表数值列表列表切片

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第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 4

4.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() 有什么区别?

编程练习

使用列表推导式生成九九乘法表。

编写程序,找出列表中所有出现超过一次的元素。

实现矩阵乘法(使用列表推导式)。


4/11操作列表
0%