上下文管理器中读取压缩CSV时多次列表推导后续返回空列表如何解决
根因说明
csv.reader() 配合 codecs.iterdecode() 返回的是单次迭代器,文件流会在第一次遍历完成后走到末尾,再次遍历迭代器时已经没有剩余数据,所以后续列表推导式返回空列表。
解决方案
方案1:单次遍历收集多列(推荐,适合大文件)
仅遍历文件一次,同步收集所有需要的列,无需加载全量文件到内存,性能最优:
import gzip import csv import codecs with gzip.open(r"myfile.csv.gz", "r") as f: content = csv.reader(codecs.iterdecode(f, "utf-8")) # 跳过表头行,如果需要保留表头数据可删除下一行 next(content) col_2 = [] col_3 = [] for row in content: col_2.append(row[1]) col_3.append(row[2]) print("col_2:", col_2) print("col_3:", col_3)
运行输出完全符合预期:
col_2: ['2', 'b'] col_3: ['3', 'c']
注:csv读取的单元格默认是字符串类型,如果需要转换为数字等其他类型,可以在append时自行做类型转换。
方案2:预加载全量行到列表(适合小文件)
如果文件体积较小,可先把所有行转为列表存储,后续可以多次遍历:
import gzip import csv import codecs with gzip.open(r"myfile.csv.gz", "r") as f: content = csv.reader(codecs.iterdecode(f, "utf-8")) # 加载全量行到内存 rows = list(content) # 跳过表头行,不需要则删除 rows = rows[1:] col_2 = [row[1] for row in rows] col_3 = [row[2] for row in rows]
这种写法语法更简洁,但是大文件会占用较高内存,请按需选择。
内容的提问来源于stack exchange,提问作者Omega
相关产品推荐
相关产品推荐

