第71集:列表推导式

学习目标

  1. 理解列表推导式的概念和优势
  2. 掌握基本列表推导式的语法
  3. 学会使用条件表达式过滤数据
  4. 了解嵌套列表推导式的使用
  5. 掌握列表推导式与普通循环的转换

列表推导式概念

什么是列表推导式

列表推导式(List Comprehension)是Python中创建列表的简洁语法,它允许我们通过一个表达式和迭代器来快速生成列表。相比传统的for循环,列表推导式更加简洁、易读且通常性能更好。

列表推导式的优势

  • 代码简洁:一行代码替代多行循环
  • 性能更好:比传统for循环执行更快
  • 可读性强:意图明确,易于理解
  • 函数式编程:更接近数学中的集合构建表示法

基本列表推导式

基本语法结构

# 基本语法
[expression for item in iterable]

# 传统for循环方式
result = []
for item in iterable:
    result.append(expression)

基本示例

# 1. 生成0-9的平方数
squares = [x**2 for x in range(10)]
print(f"平方数列表: {squares}")
# 输出: 平方数列表: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 2. 生成字符串列表
words = [char*3 for char in "ABC"]
print(f"重复字符: {words}")
# 输出: 重复字符: ['AAA', 'BBB', 'CCC']

# 3. 从已有列表创建新列表
numbers = [1, 2, 3, 4, 5]
doubled = [num * 2 for num in numbers]
print(f"翻倍数字: {doubled}")
# 输出: 翻倍数字: [2, 4, 6, 8, 10]

# 4. 处理字符串列表
fruits = ["apple", "banana", "cherry"]
upper_fruits = [fruit.upper() for fruit in fruits]
print(f"大写水果: {upper_fruits}")
# 输出: 大写水果: ['APPLE', 'BANANA', 'CHERRY']

# 5. 获取列表元素属性
names = ["Alice", "Bob", "Charlie"]
name_lengths = [len(name) for name in names]
print(f"姓名长度: {name_lengths}")
# 输出: 姓名长度: [5, 3, 7]

使用函数和复杂表达式

# 1. 使用数学函数
import math
angles = [0, 30, 45, 60, 90]
sin_values = [math.sin(math.radians(angle)) for angle in angles]
print(f"正弦值: {[round(val, 4) for val in sin_values]}")
# 输出: 正弦值: [0.0, 0.5, 0.7071, 0.866, 1.0]

# 2. 使用字符串方法
words = ["hello world", "python programming", "list comprehension"]
title_cases = [word.title() for word in words]
print(f"标题格式: {title_cases}")
# 输出: 标题格式: ['Hello World', 'Python Programming', 'List Comprehension']

# 3. 处理字典列表
students = [
    {"name": "张三", "score": 85},
    {"name": "李四", "score": 92},
    {"name": "王五", "score": 78}
]
names = [student["name"] for student in students]
print(f"学生姓名: {names}")
# 输出: 学生姓名: ['张三', '李四', '王五']

# 4. 复杂计算
temperatures_celsius = [0, 10, 20, 30, 40]
temperatures_fahrenheit = [temp * 9/5 + 32 for temp in temperatures_celsius]
print(f"摄氏转华氏: {temperatures_fahrenheit}")
# 输出: 摄氏转华氏: [32.0, 50.0, 68.0, 86.0, 104.0]

带条件的列表推导式

基本条件语法

# 条件筛选语法
[expression for item in iterable if condition]

# 传统for循环方式
result = []
for item in iterable:
    if condition:
        result.append(expression)

条件筛选示例

# 1. 筛选偶数
numbers = range(1, 21)
even_numbers = [num for num in numbers if num % 2 == 0]
print(f"偶数: {even_numbers}")
# 输出: 偶数: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

# 2. 筛选特定条件的字符串
words = ["apple", "banana", "cherry", "date", "fig", "grape"]
short_words = [word for word in words if len(word) <= 4]
print(f"短单词(≤4字符): {short_words}")
# 输出: 短单词(≤4字符): ['date', 'fig']

# 3. 筛选列表中符合条件的元素
numbers = [12, 17, 18, 25, 30, 33, 40]
adults = [num for num in numbers if num >= 18]
print(f"成年人年龄: {adults}")
# 输出: 成年人年龄: [18, 25, 30, 33, 40]

# 4. 处理文件扩展名
files = ["report.pdf", "data.csv", "image.jpg", "document.docx", "presentation.pptx"]
image_files = [file for file in files if file.endswith(('.jpg', '.jpeg', '.png'))]
print(f"图片文件: {image_files}")
# 输出: 图片文件: ['image.jpg']

使用复杂条件

# 1. 多条件筛选
numbers = range(1, 31)
filtered = [num for num in numbers if num % 2 == 0 and num % 3 == 0]
print(f"能被2和3整除的数: {filtered}")
# 输出: 能被2和3整除的数: [6, 12, 18, 24, 30]

# 2. 字符串条件筛选
products = [
    {"name": "Laptop", "price": 1200, "category": "Electronics"},
    {"name": "Book", "price": 20, "category": "Education"},
    {"name": "Headphones", "price": 80, "category": "Electronics"},
    {"name": "Pen", "price": 2, "category": "Office"},
    {"name": "Mouse", "price": 15, "category": "Electronics"}
]

# 筛选电子产品且价格大于50的
expensive_electronics = [
    product["name"] 
    for product in products 
    if product["category"] == "Electronics" and product["price"] > 50
]
print(f"高价电子产品: {expensive_electronics}")
# 输出: 高价电子产品: ['Laptop', 'Headphones']

# 3. 使用函数作为条件
def is_prime(n):
    """检查是否为质数"""
    if n < 2:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

numbers = range(2, 31)
prime_numbers = [num for num in numbers if is_prime(num)]
print(f"质数: {prime_numbers}")
# 输出: 质数: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

# 4. 文本处理条件
sentences = [
    "Python is powerful",
    "List comprehensions are useful",
    "Code should be readable",
    "Programming is fun"
]

# 筛选包含特定单词的句子
python_sentences = [
    sentence for sentence in sentences 
    if "python" in sentence.lower()
]
print(f"包含Python的句子: {python_sentences}")
# 输出: 包含Python的句子: ['Python is powerful']

条件表达式与列表推导式

条件表达式语法

# 条件表达式语法
[expression_if_true if condition else expression_if_false for item in iterable]

# 传统if-else方式
result = []
for item in iterable:
    if condition:
        result.append(expression_if_true)
    else:
        result.append(expression_if_false)

条件表达式示例

# 1. 根据条件生成不同值
numbers = range(-5, 6)
absolute_values = [num if num >= 0 else -num for num in numbers]
print(f"绝对值: {absolute_values}")
# 输出: 绝对值: [5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5]

# 2. 分类标签
scores = [95, 67, 82, 45, 73, 88, 52]
grades = [
    "优秀" if score >= 85 
    else "良好" if score >= 70 
    else "及格" if score >= 60 
    else "不及格" 
    for score in scores
]

students = list(zip(scores, grades))
print("成绩等级:")
for score, grade in students:
    print(f"  {score}分: {grade}")
# 输出:
# 成绩等级:
#   95分: 优秀
#   67分: 及格
#   82分: 良好
#   45分: 不及格
#   73分: 良好
#   88分: 优秀
#   52分: 不及格

# 3. 处理边界情况
numbers = [1, 2, 0, -1, -2, 3, -3]
safe_division = [
    1/num if num != 0 else 0 for num in numbers
]
print(f"安全除法结果: {safe_division}")
# 输出: 安全除法结果: [1.0, 0.5, 0, -1.0, -0.5, 0.3333333333333333, -0.3333333333333333]

# 4. 字符串处理
words = ["", "hello", "world", "", "python", ""]
processed_words = [
    word.upper() if word else "EMPTY" for word in words
]
print(f"处理后的单词: {processed_words}")
# 输出: 处理后的单词: ['EMPTY', 'HELLO', 'WORLD', 'EMPTY', 'PYTHON', 'EMPTY']

结合条件表达式和条件筛选

# 1. 复杂的嵌套条件
numbers = range(1, 21)
categorized = [
    "小质数" if num in [2, 3, 5, 7] 
    else "大质数" if num > 10 and num in [11, 13, 17, 19]
    else "普通奇数" if num % 2 == 1
    else "偶数"
    for num in numbers
]
print("数字分类:")
for num, category in zip(numbers, categorized):
    print(f"  {num}: {category}")
# 输出:
# 数字分类:
#   1: 普通奇数
#   2: 小质数
#   3: 小质数
#   4: 偶数
#   5: 小质数
#   6: 偶数
#   7: 小质数
#   8: 偶数
#   9: 普通奇数
#   10: 偶数
#   11: 大质数
#   12: 偶数
#   13: 大质数
#   14: 偶数
#   15: 普通奇数
#   16: 偶数
#   17: 大质数
#   18: 偶数
#   19: 大质数
#   20: 偶数

# 2. 实际业务场景
orders = [
    {"id": 1, "amount": 120, "status": "completed"},
    {"id": 2, "amount": 80, "status": "pending"},
    {"id": 3, "amount": 200, "status": "cancelled"},
    {"id": 4, "amount": 50, "status": "completed"},
    {"id": 5, "amount": 150, "status": "completed"}
]

# 处理订单:只处理完成的订单,并根据金额给出折扣
processed_orders = [
    {
        "id": order["id"],
        "amount": order["amount"] * 0.9 if order["amount"] > 100 else order["amount"],
        "discount": "10%" if order["amount"] > 100 else "无折扣"
    }
    for order in orders if order["status"] == "completed"
]

print("已处理订单:")
for order in processed_orders:
    print(f"  订单{order['id']}: 原价¥{order['amount']/0.9:.2f}, 实付¥{order['amount']:.2f}, {order['discount']}")
# 输出:
# 已处理订单:
#   订单1: 原价¥120.00, 实付¥108.00, 10%
#   订单4: 原价¥50.00, 实付¥50.00, 无折扣
#   订单5: 原价¥150.00, 实付¥135.00, 10%

嵌套列表推导式

嵌套语法

# 嵌套列表推导式语法
[expression for outer_item in outer_iterable for inner_item in inner_iterable]

# 传统嵌套循环方式
result = []
for outer_item in outer_iterable:
    for inner_item in inner_iterable:
        result.append(expression)

嵌套示例

# 1. 二维列表扁平化
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

flattened = [num for row in matrix for num in row]
print(f"扁平化列表: {flattened}")
# 输出: 扁平化列表: [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 2. 笛卡尔积
colors = ["红色", "蓝色", "绿色"]
sizes = ["小", "中", "大"]
combinations = [f"{color}{size}尺寸" for color in colors for size in sizes]
print(f"组合: {combinations}")
# 输出: 组合: ['红色小尺寸', '红色中尺寸', '红色大尺寸', '蓝色小尺寸', '蓝色中尺寸', '蓝色大尺寸', '绿色小尺寸', '绿色中尺寸', '绿色大尺寸']

# 3. 坐标点生成
x_coords = range(3)  # 0, 1, 2
y_coords = range(3)  # 0, 1, 2
points = [(x, y) for x in x_coords for y in y_coords]
print(f"坐标点: {points}")
# 输出: 坐标点: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

# 4. 嵌套字符串处理
words = ["Hello", "World"]
chars = [char.upper() for word in words for char in word if char.lower() in 'aeiou']
print(f"元音字母: {chars}")
# 输出: 元音字母: ['E', 'O', 'O']

带条件的嵌套推导式

# 1. 筛选特定组合
adjectives = ["漂亮的", "聪明的", "友好的"]
nouns = ["狗", "猫", "兔子"]
# 只创建包含"狗"的组合
dog_combinations = [f"{adj}{noun}" for adj in adjectives for noun in nouns if noun == "狗"]
print(f"狗狗的组合: {dog_combinations}")
# 输出: 狗狗的组合: ['漂亮的狗', '聪明的狗', '友好的狗']

# 2. 处理矩阵元素
matrix = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
]

# 提取偶数并计算它们的平方
even_squares = [num**2 for row in matrix for num in row if num % 2 == 0]
print(f"偶数的平方: {even_squares}")
# 输出: 偶数的平方: [4, 16, 36, 64, 100, 144]

# 3. 嵌套条件表达式
grid = range(1, 10)  # 1-9的数字
cell_descriptions = [
    f"({x},{y}) {'角落' if (x==1 or x==3) and (y==1 or y==3) else '边缘' if x==1 or x==3 or y==1 or y==3 else '中心'}"
    for y in range(1, 4) 
    for x in range(1, 4)
]

# 重塑为3x3网格
for i in range(0, 9, 3):
    print(cell_descriptions[i:i+3])
# 输出:
# ['(1,1) 角落', '(2,1) 边缘', '(3,1) 角落']
# ['(1,2) 边缘', '(2,2) 中心', '(3,2) 边缘']
# ['(1,3) 角落', '(2,3) 边缘', '(3,3) 角落']

列表推导式的应用案例

案例1:数据处理

# 1. 数据清洗
raw_data = ["apple", "  banana", "CHERRY", " date ", "FIG", "  grape  "]

# 清洗数据:去除空格,转换为小写,移除空字符串
cleaned_data = [
    item.strip().lower() 
    for item in raw_data 
    if item.strip()
]
print(f"清洗后的数据: {cleaned_data}")
# 输出: 清洗后的数据: ['apple', 'banana', 'cherry', 'date', 'fig', 'grape']

# 2. 数据转换
students_data = [
    {"name": "张三", "score": 85, "age": 20},
    {"name": "李四", "score": 92, "age": 21},
    {"name": "王五", "score": 78, "age": 19},
    {"name": "赵六", "score": 88, "age": 22}
]

# 计算每个学生的总分(假设基础分50分)
total_scores = [
    {
        "name": student["name"],
        "total_score": student["score"] + 50,
        "grade": "优秀" if student["score"] >= 85 else "良好" if student["score"] >= 75 else "及格"
    }
    for student in students_data
]

print("学生总评:")
for student in total_scores:
    print(f"  {student['name']}: {student['total_score']}分 ({student['grade']})")
# 输出:
# 学生总评:
#   张三: 135分 (优秀)
#   李四: 142分 (优秀)
#   王五: 128分 (良好)
#   赵六: 138分 (优秀)

案例2:文本处理

# 1. 文本分析
text = "Python是一种广泛使用的高级编程语言,它具有简洁明了的语法,强大的功能,丰富的库。"
words = text.split(",")

# 分析每个分句
sentence_analysis = [
    {
        "sentence": sentence,
        "length": len(sentence),
        "word_count": len(sentence.split()),
        "has_数字": any(char.isdigit() for char in sentence)
    }
    for sentence in words if sentence
]

print("句子分析:")
for analysis in sentence_analysis:
    print(f"  句子: {analysis['sentence']}")
    print(f"    长度: {analysis['length']}")
    print(f"    词数: {analysis['word_count']}")
    print(f"    含数字: {analysis['has_数字']}")
    print()

# 2. 关键词提取
document = """
Python是一种高级编程语言。Python设计哲学强调代码的可读性。
Python的语法简洁明了,使得程序员能够用更少的代码表达想法。
Python支持多种编程范式,包括面向对象、命令式、函数式和过程式编程。
"""

# 提取包含"Python"的句子
sentences = [s.strip() for s in document.split("。") if s.strip()]
python_sentences = [s for s in sentences if "Python" in s]

print("包含Python的句子:")
for i, sentence in enumerate(python_sentences, 1):
    print(f"  {i}. {sentence}")

# 3. 单词统计
article = "Python is great. Python is popular. Python is powerful."
words = [word.strip(". ").lower() for word in article.split()]
word_frequency = {}

for word in set(words):
    word_frequency[word] = words.count(word)

print(f"词频统计: {word_frequency}")
# 输出: 词频统计: {'python': 3, 'is': 3, 'great': 1, 'popular': 1, 'powerful': 1}

案例3:数学计算

# 1. 生成数学序列
# 斐波那契数列的前10项
fibonacci = [0, 1]
[fibonacci.append(fibonacci[-1] + fibonacci[-2]) for _ in range(8)]
print(f"斐波那契数列: {fibonacci}")
# 输出: 斐波那契数列: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

# 2. 质数计算
def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

primes_up_to_50 = [n for n in range(2, 51) if is_prime(n)]
print(f"50以内的质数: {primes_up_to_50}")
# 输出: 50以内的质数: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

# 3. 数学函数计算
import math
angles = range(0, 361, 30)  # 0°, 30°, 60°, ..., 360°

trig_values = [
    {
        "angle": angle,
        "sin": round(math.sin(math.radians(angle)), 4),
        "cos": round(math.cos(math.radians(angle)), 4),
        "tan": round(math.tan(math.radians(angle)), 4) if angle % 90 != 0 else "undefined"
    }
    for angle in angles
]

print("三角函数值:")
for calc in trig_values[:4]:  # 只显示前4个
    print(f"  {calc['angle']}°: sin={calc['sin']}, cos={calc['cos']}, tan={calc['tan']}")

# 4. 统计计算
scores = [85, 92, 78, 88, 95, 76, 89, 91, 84, 87]

# 计算统计量
n = len(scores)
mean = sum(scores) / n
variance = sum((x - mean) ** 2 for x in scores) / n
std_dev = variance ** 0.5

statistics = {
    "count": n,
    "mean": round(mean, 2),
    "variance": round(variance, 2),
    "std_dev": round(std_dev, 2),
    "min": min(scores),
    "max": max(scores),
    "range": max(scores) - min(scores)
}

print("分数统计:")
for key, value in statistics.items():
    print(f"  {key}: {value}")
# 输出:
# 分数统计:
#   count: 10
#   mean: 86.5
#   variance: 33.65
#   std_dev: 5.8
#   min: 76
#   max: 95
#   range: 19

列表推导式与普通循环的转换

从循环转换为推导式

# 1. 简单for循环转换
# 传统方式
squares_traditional = []
for i in range(10):
    squares_traditional.append(i ** 2)

# 列表推导式
squares_comprehension = [i ** 2 for i in range(10)]

print(f"传统方式: {squares_traditional}")
print(f"推导式方式: {squares_comprehension}")
# 输出:
# 传统方式: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 推导式方式: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 2. 带条件的for循环转换
# 传统方式
even_numbers_traditional = []
for i in range(1, 21):
    if i % 2 == 0:
        even_numbers_traditional.append(i)

# 列表推导式
even_numbers_comprehension = [i for i in range(1, 21) if i % 2 == 0]

print(f"传统方式: {even_numbers_traditional}")
print(f"推导式方式: {even_numbers_comprehension}")
# 输出:
# 传统方式: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# 推导式方式: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

# 3. 带if-else的for循环转换
# 传统方式
absolute_values_traditional = []
for i in range(-5, 6):
    if i >= 0:
        absolute_values_traditional.append(i)
    else:
        absolute_values_traditional.append(-i)

# 列表推导式
absolute_values_comprehension = [i if i >= 0 else -i for i in range(-5, 6)]

print(f"传统方式: {absolute_values_traditional}")
print(f"推导式方式: {absolute_values_comprehension}")
# 输出:
# 传统方式: [5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5]
# 推导式方式: [5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5]

# 4. 嵌套循环转换
# 传统方式
matrix_traditional = []
for i in range(3):
    row = []
    for j in range(3):
        row.append(i * j)
    matrix_traditional.append(row)

# 列表推导式
matrix_comprehension = [[i * j for j in range(3)] for i in range(3)]

print("传统方式:")
for row in matrix_traditional:
    print(f"  {row}")

print("推导式方式:")
for row in matrix_comprehension:
    print(f"  {row}")
# 输出:
# 传统方式:
#   [0, 0, 0]
#   [0, 1, 2]
#   [0, 2, 4]
# 推导式方式:
#   [0, 0, 0]
#   [0, 1, 2]
#   [0, 2, 4]

性能对比

import time

# 1. 大数据集性能测试
large_range = range(100000)

# 传统for循环
start_time = time.time()
squares_traditional = []
for i in large_range:
    squares_traditional.append(i ** 2)
traditional_time = time.time() - start_time

# 列表推导式
start_time = time.time()
squares_comprehension = [i ** 2 for i in large_range]
comprehension_time = time.time() - start_time

print(f"传统for循环时间: {traditional_time:.6f}秒")
print(f"列表推导式时间: {comprehension_time:.6f}秒")
print(f"性能提升: {traditional_time/comprehension_time:.2f}倍")

# 2. 带条件的性能测试
# 传统for循环
start_time = time.time()
even_traditional = []
for i in large_range:
    if i % 2 == 0:
        even_traditional.append(i)
traditional_even_time = time.time() - start_time

# 列表推导式
start_time = time.time()
even_comprehension = [i for i in large_range if i % 2 == 0]
comprehension_even_time = time.time() - start_time

print(f"\n传统for循环(带条件)时间: {traditional_even_time:.6f}秒")
print(f"列表推导式(带条件)时间: {comprehension_even_time:.6f}秒")
print(f"性能提升: {traditional_even_time/comprehension_even_time:.2f}倍")

列表推导式的局限性

何时不应使用列表推导式

# 1. 复杂逻辑不适合列表推导式
# 不推荐:过于复杂的列表推导式
complex_result = [
    x**2 + y**2 if (x + y) % 2 == 0 else (x - y)**2 
    for x in range(5) 
    for y in range(5) 
    if x != y and (x * y) % 3 == 0
]

# 推荐:使用传统循环,更清晰
complex_result = []
for x in range(5):
    for y in range(5):
        if x != y and (x * y) % 3 == 0:
            if (x + y) % 2 == 0:
                complex_result.append(x**2 + y**2)
            else:
                complex_result.append((x - y)**2)

# 2. 需要副作用的情况
# 不推荐:列表推导式用于副作用
[print(f"Processing {item}") for item in range(5)]  # 创建了不需要的列表

# 推荐:使用传统循环
for item in range(5):
    print(f"Processing {item}")

# 3. 需要异常处理的情况
# 不推荐:列表推导式中包含try-except
numbers = [1, 2, 0, 4, 5]
division_results = [
    num // den 
    for num in numbers 
    for den in range(1, 6)
    if den != 0  # 避免除以零,但不如异常处理灵活
]

# 推荐:传统循环中处理异常
division_results_safe = []
for num in numbers:
    for den in range(1, 6):
        try:
            division_results_safe.append(num // den)
        except ZeroDivisionError:
            print(f"跳过除零: {num}/{den}")

可读性考虑

# 1. 过长的列表推导式
# 不推荐:难以阅读
result = [x**2 for x in range(100) if x % 2 == 0 and x % 3 == 0 and x % 5 == 0]

# 推荐:拆分成多行或使用中间变量
result = [
    x**2 
    for x in range(100) 
    if x % 2 == 0 and x % 3 == 0 and x % 5 == 0
]

# 更推荐:使用函数
def meets_conditions(x):
    return x % 2 == 0 and x % 3 == 0 and x % 5 == 0

result = [x**2 for x in range(100) if meets_conditions(x)]

# 2. 嵌套过深
# 不推荐:三层嵌套推导式
result = [x + y + z for x in range(3) for y in range(3) for z in range(3)]

# 推荐:拆分成多个步骤或使用传统循环
intermediate = []
for x in range(3):
    for y in range(3):
        for z in range(3):
            intermediate.append(x + y + z)
result = intermediate

列表推导式与其他推导式

元组推导式

# 注意:Python没有真正的元组推导式语法,但可以通过生成器表达式创建元组
# 使用生成器表达式转换为元组
tuple_squares = tuple(x**2 for x in range(10))
print(f"元组平方数: {tuple_squares}")
# 输出: 元组平方数: (0, 1, 4, 9, 16, 25, 36, 49, 64, 81)

# 错误的做法:这会创建生成器对象,不是元组
squares_generator = (x**2 for x in range(10))
print(f"生成器对象: {squares_generator}")  # 这是一个生成器对象

集合推导式

# 集合推导式语法:{expression for item in iterable}
words = ["apple", "banana", "cherry", "apple", "banana"]
unique_lengths = {len(word) for word in words}
print(f"唯一长度集合: {unique_lengths}")
# 输出: 唯一长度集合: {5, 6}

# 去重并转换大写
unique_words_upper = {word.upper() for word in words}
print(f"唯一单词大写: {unique_words_upper}")
# 输出: 唯一单词大写: {'BANANA', 'CHERRY', 'APPLE'}

字典推导式

# 字典推导式语法:{key_expression: value_expression for item in iterable}
words = ["apple", "banana", "cherry"]
word_length_dict = {word: len(word) for word in words}
print(f"单词长度字典: {word_length_dict}")
# 输出: 单词长度字典: {'apple': 5, 'banana': 6, 'cherry': 6}

# 从字典创建新字典
original_dict = {'a': 1, 'b': 2, 'c': 3}
squared_dict = {key: value**2 for key, value in original_dict.items()}
print(f"平方值字典: {squared_dict}")
# 输出: 平方值字典: {'a': 1, 'b': 4, 'c': 9}

# 带条件的字典推导式
filtered_dict = {key: value for key, value in original_dict.items() if value % 2 == 1}
print(f"奇数值字典: {filtered_dict}")
# 输出: 奇数值字典: {'a': 1, 'c': 3}

常见错误

错误1:语法错误

# 错误:缺少方括号
# squares = x**2 for x in range(10)  # 语法错误

# 正确:使用方括号
squares = [x**2 for x in range(10)]

# 错误:混淆if条件的位置
# squares = [x**2 if x % 2 == 0 for x in range(10)]  # 语法错误

# 正确:条件放在for后面
squares = [x**2 for x in range(10) if x % 2 == 0]

# 错误:if-else位置错误
# squares = [x**2 if x % 2 == 0 else 0 for x in range(10) if x > 5]  # 语法错误

# 正确:if-else在表达式内部,if条件在for后面
squares = [x**2 if x % 2 == 0 else 0 for x in range(10) if x > 5]

错误2:逻辑错误

# 错误:变量名冲突
numbers = [1, 2, 3, 4, 5]
# result = [x for x in numbers if x > numbers]  # 错误:numbers是列表,不是数字

# 正确:使用正确的比较
result = [x for x in numbers if x > 3]

# 错误:作用域问题
# x = 10
# result = [x * 2 for x in range(5)]
# print(x)  # x的值可能被推导式改变,在Python 3中不会,但在某些情况下可能混淆

# 正确:避免使用可能冲突的变量名
result = [num * 2 for num in range(5)]

错误3:性能问题

# 不推荐:在推导式中调用复杂函数
def complex_calculation(x):
    # 模拟耗时计算
    result = x
    for i in range(1000):
        result = (result + i) % 100
    return result

# 每次调用都会执行复杂计算
# result = [complex_calculation(x) for x in range(100)]

# 推荐:考虑是否需要推导式,传统循环可能更合适
result = []
for x in range(100):
    result.append(complex_calculation(x))

课后练习

  1. 使用列表推导式创建1-20的数字,然后筛选出所有能被3整除的数字。

  2. 给定一个字符串列表,使用列表推导式创建一个新列表,包含所有长度大于5的字符串的大写形式。

  3. 创建一个字典推导式,将数字1-10作为键,它们的平方作为值。

  4. 使用嵌套列表推导式创建一个3×3的乘法表矩阵。

  5. 给定学生成绩列表,使用列表推导式计算每个学生的等级(90-100为优秀,80-89为良好,70-79为中等,60-69为及格,0-59为不及格)。

总结

列表推导式是Python的强大特性:

核心优势

  • 代码简洁:一行代码替代多行循环
  • 性能优秀:比传统for循环执行更快
  • 可读性强:意图明确,表达式化
  • 功能强大:支持条件表达式和嵌套

应用场景

  • 数据转换:将一种格式的数据转换为另一种
  • 数据筛选:根据条件过滤数据
  • 数学计算:生成数学序列和计算结果
  • 文本处理:处理和分析文本数据

使用建议

  • 适度使用:不要过度追求简洁而牺牲可读性
  • 保持简单:复杂逻辑使用传统循环
  • 性能考虑:大数据量时测试性能差异
  • 正确语法:注意if/if-else的位置和语法

列表推导式是Pythonic代码的重要组成部分,掌握它能显著提高编程效率和代码质量。

« 上一篇 面向对象设计原则 下一篇 » 字典推导式