循环向列表append值时覆盖旧值,求Python代码问题排查
问题描述
我尝试从CSV文件读取关键词,在PDF文本对象中按页索引这些关键词的页码。读写流程整体正常,但向page_list追加新页码时,不仅将新值添加到列表末尾,还会覆盖列表中所有原有值。输出的CSV包含预期的所有关键词,列表长度符合预期,但列表内所有值均被最新页码替换。
怀疑问题出在for w in words循环中,当前使用的函数代码如下:
data = pd.read_csv(index) for da in data: words=data[da].values with open(pdf, 'rb') as f: readerobj = PdfFileReader(f) pages = readerobj.numPages page_dict={} # eventual index # read pdf page by page count=0 for i in range(pages): page_list=[] if i in range1: continue else: count+=1 page = readerobj.getPage(i) reader=page.extractText() pdfobj = nltk.word_tokenize(str(reader)) for w in words: # Overwriting every value in list if str(w) in str(pdfobj): page_list.append(count) page_dict[w]=page_list with open('Index.csv', 'w', encoding="utf-8") as x: writer = csv.writer(x) for key, value in page_dict.items(): writer.writerow([key, value]) f.close()
预期输出的CSV格式类似:
word1: [1,4,8,23] word2: [1,3,5,7,22,33]
但实际输出为:
word1: [23,23,23,23] word2: [33,33,33,33,33,33]
问题原因与修复
核心问题
- 列表引用共享:你在每页循环里初始化
page_list=[],但所有匹配的关键词都指向同一个列表对象。因为列表是引用类型,后续对这个列表的修改会同步影响所有关键词对应的列表内容。 - 逻辑重复追加:当某页有多个关键词匹配时,你会把当前页码多次追加到同一个
page_list,再把这个列表赋值给每个匹配的关键词,导致列表里的页码重复累积,最终全被最后一页的页码覆盖。 - 文件写入时机错误:每页循环都打开并写入CSV,既浪费性能,还会重复覆盖文件内容。
修正后的代码
import pandas as pd from PyPDF2 import PdfFileReader import nltk import csv data = pd.read_csv(index) for da in data: words = data[da].values # 提前为每个关键词创建独立的空列表,彻底避免引用共享 page_dict = {w: [] for w in words} with open(pdf, 'rb') as f: readerobj = PdfFileReader(f) pages = readerobj.numPages count = 0 for i in range(pages): if i in range1: continue count += 1 page = readerobj.getPage(i) reader = page.extractText() pdfobj = nltk.word_tokenize(str(reader)) for w in words: if str(w) in str(pdfobj): # 直接向当前关键词的专属列表追加页码 page_dict[w].append(count) # 所有页面处理完成后统一写入CSV with open('Index.csv', 'w', encoding="utf-8", newline='') as x: writer = csv.writer(x) for key, value in page_dict.items(): writer.writerow([key, value])
关键修改点
- 用字典推导式
page_dict = {w: [] for w in words}提前为每个关键词分配独立的空列表,彻底解决引用共享问题。 - 移除每页的
page_list,直接操作对应关键词的列表,确保每个页码仅被追加一次到匹配的关键词列表中。 - 将CSV写入操作移到所有页面处理完成后,只执行一次,提升效率。
- 去掉冗余的
f.close(),with语句会自动处理文件关闭。
内容的提问来源于stack exchange,提问作者mr56
相关产品推荐
相关产品推荐

