如何确定循环嵌套顺序?文件单次遍历异常排查及目标条目匹配需求
文件遍历与日期循环的问题解析
首先先解决你代码里的核心bug:为什么只遍历了一次文件行?
这是因为Python里的文件对象是单向迭代器——当你第一次用for line in logFile遍历完所有行之后,文件的读取指针已经移动到了文件末尾。后面再执行for line in logFile时,迭代器已经没有剩余内容可以返回了,所以后续的日期循环里根本不会再遍历文件内容。
先解决你的最终需求:找到指定行就退出
你的目标是找到Account Movement Report,2019-05-09,13:53:38,13:53:38,R这一行就停止,最高效的写法是只遍历文件一次,逐行检查是否符合条件,不需要循环所有日期:
target_report = "Account Movement Report" target_date = "2019-05-09" target_status = "R" with open(r'reportLog.txt','r') as logFile: for line in logFile: # 先分割行内容,避免字符串匹配的冗余 parts = line.strip().split(',') if len(parts) >=4 and parts[0] == target_report and parts[1] == target_date and parts[4] == target_status: print('found') break else: print('not found')
这种写法只需要读一次文件,找到目标就立刻终止,IO成本最低,逻辑也最直接。
回答你的两个疑问
1. 怎么用程序员的思维选择循环顺序?
核心要围绕成本优先级来思考,优先级从高到低是:
- 磁盘IO成本 > 内存计算成本 > 循环次数
磁盘读取是程序里相对最慢的操作,所以第一原则是尽量减少文件遍历的次数。 - 然后看数据规模:
- 如果文件极大,日期范围很小:可以先把文件里所有符合日期范围的行过滤出来(一次遍历),再在这些行里找目标;
- 如果文件很小,日期范围极大:哪怕多次遍历文件,性能影响也可以忽略,怎么写方便怎么来;
- 如果有“找到就退出”的终止条件:优先遍历文件,逐行检查,一旦命中就停止,避免做无用功。
简单说:能只读一次文件就解决的,绝对不要读多次。
2. 为什么代码只遍历了一次文件行?
刚才已经提到了,文件对象是单向迭代器。可以做个小测试验证:
with open('reportLog.txt','r') as f: print(list(f)) # 第一次遍历,把所有行转成列表 print(list(f)) # 第二次遍历,返回空列表
第一次遍历后,文件指针已经到了末尾,后续的迭代就没有内容了。如果非要用你原来的“先循环日期再遍历文件”的写法,需要每次重新读取文件,或者先把文件内容全部读到内存里:
# 先把文件内容读到内存,避免多次IO with open(r'reportLog.txt','r') as logFile: lines = logFile.readlines() for single_date in daterange(start_date, end_date): for line in lines: if all(var in line for var in (reportName, str(single_date), 'R')): print('found') break else: print('not found')
但这种写法的问题是,如果文件很大,会占用大量内存,所以除非必要,不推荐。
内容的提问来源于stack exchange,提问作者JMac
相关产品推荐
相关产品推荐

