目录
1.open
参数总览
mode 参数
encoding 编码参数
errors 错误处理参数
2.enumerate
参数
返回值
应用
3.zip
语法参数
特点
4.生成器
生成器的两种创建方式
生成器的核心方法
细节
1.open
参数总览
| 参数 | 类型 | 默认值 | 说明 | 示例 |
|---|---|---|---|---|
file | str | 必需 | 文件路径(绝对/相对路径) | 'data.txt'、'./folder/file.csv' |
mode | str | 'r' | 文件打开模式 | 'r'、'w'、'a'、'rb'、'w+' |
encoding | str | None(平台依赖) | 文本编码方式 | 'utf-8'、'gbk'、'ascii' |
errors | str | 'strict' | 编码错误处理方式 | 'ignore'、'replace'、'strict' |
newline | str | None | 换行符处理 | '\n'、'\r\n'、'' |
buffering | int | -1 | 缓冲策略 | 1(行缓冲)、0(无缓冲) |
closefd | bool | True | 是否关闭文件描述符 | True、Falseopen() 函数核心参数 |
mode 参数
| mode | 读写 | 文件存在 | 文件不存在 | 指针位置 | 典型用途 |
|---|---|---|---|---|---|
'r' | 只读 | 打开 | 报错FileNotFoundError | 开头 | 读取文本文件 |
'w' | 只写 | 清空内容 | 创建新文件 | 开头 | 写入/覆盖文件 |
'a' | 只写 | 保留内容 | 创建新文件 | 末尾 | 追加内容 |
'x' | 只写 | 报错FileExistsError | 创建新文件 | 开头 | 安全创建新文件 |
'r+' | 读写 | 打开 | 报错 | 开头 | 读取并修改 |
'w+' | 读写 | 清空内容 | 创建新文件 | 开头 | 读写(会清空) |
'a+' | 读写 | 保留内容 | 创建新文件 | 末尾 | 读取+追加 |
'rb' | 只读(二进制) | 打开 | 报错 | 开头 | 图片、音频等 |
'wb' | 只写(二进制) | 清空内容 | 创建新文件 | 开头 | 写入二进制数据 |
'ab' | 追加(二进制) | 保留内容 | 创建新文件 | 末尾 | 追加二进制数据 |
encoding 编码参数
| 编码 | 说明 | 适用场景 |
|---|---|---|
'utf-8' | 国际通用编码 | 最推荐,跨平台,支持所有语言 |
'gbk' | 简体中文扩展 | Windows中文环境遗留文件 |
'gb2312' | 简体中文(旧) | 老旧Windows系统文件 |
'ascii' | 英文字符 | 纯英文文件(中文会报错) |
'utf-8-sig' | 带BOM的UTF-8 | 处理Excel导出的UTF-8文件 |
errors 错误处理参数
| 值 | 行为 | 示例效果 |
|---|---|---|
'strict' | 遇到错误立即报错 | 默认,最严格 |
'ignore' | 忽略错误字符 | '你好\x80世界'→'你好世界' |
'replace' | 用�替换错误字符 | '你好\x80世界'→'你好�世界' |
'backslashreplace' | 用转义序列替换 | '\x80'→'\\x80' |
- 示例
| 使用场景 | 代码 | 说明 |
|---|---|---|
| 读UTF-8文本 | open('file.txt', 'r', encoding='utf-8') | 最常用 |
| 写UTF-8文本 | open('file.txt', 'w', encoding='utf-8') | 覆盖写入 |
| 追加文本 | open('file.txt', 'a', encoding='utf-8') | 保留原内容 |
| 读二进制 | open('image.jpg', 'rb') | 图片/视频 |
| 写二进制 | open('output.jpg', 'wb') | 下载文件 |
| 读写模式 | open('file.txt', 'r+', encoding='utf-8') | 需手动控制指针 |
| 安全创建 | open('new.txt', 'x', encoding='utf-8') | 防止覆盖 |
| 忽略编码错误 | open('bad.txt', 'r', encoding='utf-8', errors='ignore') | 容忍乱码 |
# 最常用的3种写法 with open('file.txt', 'r', encoding='utf-8') as f: # 读 data = f.read() with open('file.txt', 'w', encoding='utf-8') as f: # 写 f.write('Hello') with open('file.txt', 'a', encoding='utf-8') as f: # 追加 f.write('New line')2.enumerate
核心作用:在迭代可迭代对象时,自动生成索引,避免手动维护计数器
# 没有 enumerate(原始方式) fruits = ['apple', 'banana', 'orange'] index = 0 for fruit in fruits: print(index, fruit) index += 1 # 输出:0 apple, 1 banana, 2 orange # 使用 enumerate(优雅方式) for index, fruit in enumerate(fruits): print(index, fruit) # 输出完全相同,但代码更简洁参数
| 参数 | 类型 | 默认值 | 说明 | 示例 |
|---|---|---|---|---|
iterable | 可迭代对象 | 必需 | 任何支持迭代的对象 | 列表、元组、字符串、字典等 |
start | int | 0 | 起始索引值 | 1、10、-5 |
# start 参数示例 colors = ['red', 'green', 'blue'] # 从0开始(默认) for i, color in enumerate(colors): print(i, color) # 0 red, 1 green, 2 blue # 从1开始(人类友好) for i, color in enumerate(colors, start=1): print(i, color) # 1 red, 2 green, 3 blue # 从10开始 for i, color in enumerate(colors, 10): print(i, color) # 10 red, 11 green, 12 blue返回值
enumerate() 返回一个枚举对象(迭代器),每次产生一个元组 (索引, 值)
# 查看 enumerate 对象 fruits = ['apple', 'banana', 'orange'] e = enumerate(fruits) print(e) # <enumerate object at 0x...> print(type(e)) # <class 'enumerate'> print(list(e)) # [(0, 'apple'), (1, 'banana'), (2, 'orange')] # 枚举对象只能迭代一次(迭代器特性) e = enumerate(fruits) print(list(e)) # [(0, 'apple'), (1, 'banana'), (2, 'orange')] print(list(e)) # [] 第二次为空! # 手动获取下一个值 e = enumerate(fruits) print(next(e)) # (0, 'apple') print(next(e)) # (1, 'banana')应用
| 数据类型 | 示例 | 输出 | 注意点 |
|---|---|---|---|
| 列表 | enumerate([a,b,c]) | (0,a), (1,b), (2,c) | 最常用 |
| 元组 | enumerate((a,b,c)) | (0,a), (1,b), (2,c) | 同列表 |
| 字符串 | enumerate("abc") | (0,'a'), (1,'b'), (2,'c') | 字符索引 |
| 字典 | enumerate(dict) | (0,key1), (1,key2) | 只迭代键 |
| 集合 | enumerate(set) | (0,item1)... | 顺序不确定 |
| 文件对象 | enumerate(file) | (0,line1), (1,line2) | 逐行索引 |
- 总是用 enumerate 而不是 range(len()) 或手动计数器
- 记住 start 参数可以改变起始索引(通常设为1)
- enumerate 返回迭代器,只能使用一次
- 配合列表推导式可以优雅地创建索引映射
- 遍历字典时用 enumerate(dict.items()) 获取索引、键、值
# 推荐:使用 enumerate 替代 range(len()) for i, item in enumerate(collection): process(i, item) # 推荐:从1开始计数(人类友好) for line_num, line in enumerate(file, 1): print(f"第{line_num}行: {line}") # 推荐:创建索引映射 index_map = {item: i for i, item in enumerate(unique_items)} # 推荐:同时需要索引和修改元素 for i, value in enumerate(lst): lst[i] = transform(value) # 避免:手动维护计数器 i = 0 for item in collection: process(i, item) i += 1 # 避免:使用 range(len()) 然后下标访问 for i in range(len(collection)): process(i, collection[i]) # 避免:在迭代时修改列表长度 for i, item in enumerate(lst): if condition: lst.pop(i) # 危险!3.zip
核心作用:将多个可迭代对象"拉链式"地打包成元组序列,并行聚合数据
# zip 的直观理解 names = ['Alice', 'Bob', 'Charlie'] scores = [85, 92, 78] # zip 像拉链一样将对应位置元素结合 zipped = zip(names, scores) print(list(zipped)) # [('Alice', 85), ('Bob', 92), ('Charlie', 78)]语法参数
| 参数 | 类型 | 说明 | 示例 |
|---|---|---|---|
*iterables | 可迭代对象 | 一个或多个可迭代对象 | zip([1,2], [3,4]) |
| 返回值 | zip对象 | 迭代器,产生元组 | <zip object at 0x...> |
# 不同参数数量 # 1个参数(很少用) result = zip([1, 2, 3]) print(list(result)) # [(1,), (2,), (3,)] # 2个参数(最常用) result = zip([1, 2], ['a', 'b']) print(list(result)) # [(1, 'a'), (2, 'b')] # 3个及以上参数 result = zip([1, 2], ['a', 'b'], [True, False]) print(list(result)) # [(1, 'a', True), (2, 'b', False)] # 0个参数 result = zip() print(list(result)) # []特点
- 惰性求值(返回迭代器)
# zip 返回迭代器,不是列表 data = zip([1, 2, 3], ['a', 'b', 'c']) print(data) # <zip object at 0x...> # 只能迭代一次 print(list(data)) # [(1, 'a'), (2, 'b'), (3, 'c')] print(list(data)) # [] 已经耗尽! # 重新创建才能再次使用 data = zip([1, 2, 3], ['a', 'b', 'c']) # 重新创建以最短的序列为准
# 不等长时,以最短的为准(不会报错) a = [1, 2, 3, 4, 5] b = ['a', 'b', 'c'] c = ['X', 'Y'] result = zip(a, b, c) print(list(result)) # [(1, 'a', 'X'), (2, 'b', 'Y')] # 3,4,5 和 c 都被忽略 # 如果需要以最长的为准,使用 zip_longest from itertools import zip_longest result = zip_longest(a, b, c, fillvalue='NA') print(list(result)) # [(1, 'a', 'X'), (2, 'b', 'Y'), (3, 'c', 'NA'), (4, 'NA', 'NA'), (5, 'NA', 'NA')]4.生成器
生成器是一种特殊的迭代器,它允许你惰性地(按需)生成值,而不是一次性在内存中创建所有值
# 普通列表:一次性创建所有元素 numbers_list = [i for i in range(1000000)] # 立即占用大量内存 # 生成器:按需产生元素 numbers_gen = (i for i in range(1000000)) # 几乎不占用内存生成器的两种创建方式
| 方式 | 语法 | 特点 | 适用场景 |
|---|---|---|---|
| 生成器表达式 | (表达式 for 变量 in 可迭代对象) | 简洁、一行代码 | 简单转换 |
| 生成器函数 | def func(): yield 值 | 复杂逻辑、可暂停 | 复杂流程控制 |
- 生成器表达式
# 基本语法 gen = (x**2 for x in range(10)) print(gen) # <generator object <genexpr> at 0x...> # 使用 for value in gen: print(value, end=' ') # 0 1 4 9 16 25 36 49 64 81 # 与列表推导式对比 list_comp = [x**2 for x in range(10)] # 立即创建列表 gen_exp = (x**2 for x in range(10)) # 创建生成器对象 print(list_comp) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] print(gen_exp) # <generator object <genexpr> at 0x...> # 带条件的生成器表达式 even_squares = (x**2 for x in range(20) if x % 2 == 0) print(list(even_squares)) # [0, 4, 16, 36, 64, 100, 144, 196, 256, 324]- 生成器函数(yield 关键字)
# 基础生成器函数 def count_up_to(n): """生成从0到n-1的数字""" i = 0 while i < n: yield i # 暂停并返回当前值 i += 1 # 使用生成器 counter = count_up_to(5) print(next(counter)) # 0 print(next(counter)) # 1 print(next(counter)) # 2 print(next(counter)) # 3 print(next(counter)) # 4 # print(next(counter)) # StopIteration # for 循环自动处理 StopIteration for num in count_up_to(5): print(num, end=' ') # 0 1 2 3 4生成器的核心方法
| 方法 | 作用 | 说明 |
|---|---|---|
next(g) | 获取下一个值 | 从当前yield继续执行 |
g.send(value) | 发送值给生成器 | yield 表达式会返回发送的值 |
g.throw(type) | 向生成器抛出异常 | 在yield位置抛出异常 |
g.close() | 关闭生成器 | 引发 GeneratorExit 异常 |
细节
- map/zip/enumerate 返回的是"一次性迭代器"和生成器一样只能使用一次,遍历后即销毁
- 直接打印只会显示对象的类型和内存地址,而不是内容
- 必须通过 list()、tuple()、set() 或循环等方式"消费"它才能获取数据,且消费一次后就会耗尽