Python 推导式详细教程

Python 推导式详细教程

文章目录

什么是推导式?

推导式是Python中一种简洁、高效创建数据序列的方法。它像是把循环和条件判断压缩成一行代码。

1. 列表推导式(最常用)

基本格式[表达式 for 变量 in 可迭代对象 if 条件]

示例1:基础用法
python 复制代码
# 创建一个包含0-9平方的列表
squares = [x**2 for x in range(10)]
print(squares)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
示例2:带条件过滤
python 复制代码
# 只保留偶数
even_numbers = [x for x in range(10) if x % 2 == 0]
print(even_numbers)  # [0, 2, 4, 6, 8]

# 你的示例:过滤短名字并转大写
names = ['Bob', 'Tom', 'alice', 'Jerry', 'Wendy', 'Smith']
new_names = [name.upper() for name in names if len(name) > 3]
print(new_names)  # ['ALICE', 'JERRY', 'WENDY', 'SMITH']
示例3:使用函数
python 复制代码
# 对每个元素应用函数
def process_number(x):
    return x * 2 if x > 5 else x

numbers = [1, 3, 5, 7, 9, 11]
processed = [process_number(x) for x in numbers]
print(processed)  # [1, 3, 5, 14, 18, 22]
示例4:多个变量
python 复制代码
# 两个列表组合
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
combined = [(x, y) for x in list1 for y in list2]
print(combined)  # [(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), ...]

2. 字典推导式

基本格式{键: 值 for 变量 in 可迭代对象 if 条件}

示例1:创建字典
python 复制代码
# 数字及其平方的字典
squares_dict = {x: x**2 for x in range(1, 6)}
print(squares_dict)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# 你的示例:字符串长度字典
listdemo = ['Google', 'Runoob', 'Taobao']
newdict = {key: len(key) for key in listdemo}
print(newdict)  # {'Google': 6, 'Runoob': 6, 'Taobao': 6}
示例2:条件过滤
python 复制代码
# 只处理大于10的数字
numbers = [5, 10, 15, 20]
result = {x: x*2 for x in numbers if x > 10}
print(result)  # {15: 30, 20: 40}
示例3:转换现有字典
python 复制代码
# 所有值加10
original = {'a': 1, 'b': 2, 'c': 3}
new_dict = {k: v+10 for k, v in original.items()}
print(new_dict)  # {'a': 11, 'b': 12, 'c': 13}

3. 集合推导式

基本格式{表达式 for 变量 in 可迭代对象 if 条件}

特点:自动去重

示例1:创建集合
python 复制代码
# 平方数的集合
squares_set = {x**2 for x in [1, 2, 2, 3, 3, 3, 4]}
print(squares_set)  # {16, 1, 4, 9} - 注意:顺序可能不同,集合无序

# 你的示例:过滤特定字符
a = {x for x in 'abracadabra' if x not in 'abc'}
print(a)  # 可能是 {'d', 'r'} - 无序且去重
示例2:从列表去重
python 复制代码
numbers = [1, 2, 2, 3, 3, 3, 4, 5, 5]
unique_numbers = {x for x in numbers}
print(unique_numbers)  # {1, 2, 3, 4, 5}

4. 生成器表达式(元组推导式)

基本格式(表达式 for 变量 in 可迭代对象 if 条件)

重要特点

  • 返回生成器对象,不是立即计算所有值
  • 节省内存,适合大数据处理
  • 一次性的,用完就不能再用
示例1:创建生成器
python 复制代码
# 创建生成器对象
gen = (x**2 for x in range(5))
print(gen)  # <generator object <genexpr> at 0x...>

# 逐个获取值
print(next(gen))  # 0
print(next(gen))  # 1
print(next(gen))  # 4

# 或转换为列表
remaining = list(gen)
print(remaining)  # [9, 16] - 注意:前面已经取了3个值
示例2:转换为元组
python 复制代码
# 你的示例:生成1-9的元组
a = (x for x in range(1, 10))
print(a)  # <generator object <genexpr> at 0x...>

# 转换为元组
tuple_a = tuple(a)
print(tuple_a)  # (1, 2, 3, 4, 5, 6, 7, 8, 9)
示例3:节省内存的优势
python 复制代码
# 比较列表推导式和生成器表达式的内存使用
import sys

# 列表推导式 - 占用内存
list_comp = [x**2 for x in range(1000000)]
print(f"列表占用内存: {sys.getsizeof(list_comp)} 字节")

# 生成器表达式 - 占用很少内存
gen_exp = (x**2 for x in range(1000000))
print(f"生成器占用内存: {sys.getsizeof(gen_exp)} 字节")

综合练习:一步步构建推导式

练习1:处理学生成绩

python 复制代码
# 原始数据:学生姓名和成绩
students = [('Alice', 85), ('Bob', 60), ('Charlie', 92), ('David', 45)]

# 步骤1:提取成绩大于等于60的学生
passed = [name for name, score in students if score >= 60]
print("及格的学生:", passed)  # ['Alice', 'Bob', 'Charlie']

# 步骤2:给每个学生成绩加5分(但不超过100分)
adjusted = [(name, min(score + 5, 100)) for name, score in students]
print("调整后的成绩:", adjusted)

# 步骤3:转换为字典
student_dict = {name: score for name, score in students}
print("学生字典:", student_dict)

练习2:多个条件

python 复制代码
# 创建0-20的数字列表
numbers = list(range(21))

# 找出能被2或3整除的数,但不能被5整除
result = [x for x in numbers 
          if (x % 2 == 0 or x % 3 == 0) 
          and x % 5 != 0]
print(result)  # [2, 3, 4, 6, 8, 9, 12, 14, 16, 18]

注意事项和最佳实践

1. 保持简洁

python 复制代码
# ✅ 好的写法:简单明了
even_squares = [x**2 for x in range(10) if x % 2 == 0]

# ❌ 不好的写法:过于复杂
# 如果逻辑太复杂,用普通循环

2. 避免嵌套过深

python 复制代码
# ✅ 两层以内通常可以接受
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

# ❌ 三层或以上考虑用其他方法

3. 性能考虑

python 复制代码
# 列表推导式 vs 普通循环

# 方法1:列表推导式(更快)
result1 = [x**2 for x in range(1000)]

# 方法2:普通循环(更灵活)
result2 = []
for x in range(1000):
    result2.append(x**2)

4. 使用 walrus 运算符(Python 3.8+)

python 复制代码
# 在条件中赋值
data = ["apple", "banana", "cherry", "date"]

# 只保留长度大于5的字符串,并存储长度
result = [n for s in data if (n := len(s)) > 5]
print(result)  # [6, 6]

记忆技巧

类型 括号 特点
列表推导式 [ ] 最常用,生成列表
字典推导式 { : } 生成键值对
集合推导式 { } 自动去重,无序
生成器表达式 ( ) 节省内存,一次性

小测试

检查你是否掌握了推导式:

python 复制代码
# 1. 将下面代码改为列表推导式
result = []
for i in range(10):
    if i % 2 == 0:
        result.append(i * 10)

# 答案:
result = [i * 10 for i in range(10) if i % 2 == 0]

# 2. 创建字典,键为字母,值为ASCII码
letters = 'abcde'

# 答案:
ascii_dict = {letter: ord(letter) for letter in letters}

# 3. 找出两个列表的共同元素
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 6, 7, 8]

# 答案:
common = {x for x in list1 if x in list2}

记住:推导式让代码更简洁,但不要过度使用。如果一行代码太长或太复杂,拆分成多行会更易读。

相关推荐
ljh5746491191 小时前
用vscode怎么运行conda中的python环境
vscode·python·conda
民乐团扒谱机2 小时前
【微科普】GN 算法:在网络的脉络中,寻找社群的边界
开发语言·算法·matlab·语言学·语义网络分析
秋邱2 小时前
AR 技术创新与商业化新方向:AI+AR 融合,抢占 2025 高潜力赛道
前端·人工智能·后端·python·html·restful
Stara05112 小时前
LangChain—大语言模型应用开发框架的体系化架构解析
python·langchain·llm·agent·提示工程·rag
yaoxin5211232 小时前
263. Java 集合 - 遍历 List 时选用哪种方式?ArrayList vs LinkedList
java·开发语言·list
骇客野人2 小时前
java对象和JSON对象之间的转换关系
java·开发语言·json
只与明月听2 小时前
一个有趣的面试题
前端·后端·python
lubiii_2 小时前
Aircrack-ng工具使用原理与实操笔记
开发语言·网络·web安全·php
陌上倾城落蝶雨2 小时前
django基础命令
后端·python·django