Python 2.6.6:如何找出A文件中不在B文件的元素?遇异常结果
问题分析与解决:CSV元素存在性判断无输出的原因
核心问题:csv.reader是一次性迭代器
你遇到的问题根源在于**csv.reader返回的是迭代器对象**,迭代器只能被遍历一次,遍历结束后就会耗尽,后续再访问就没有内容了。
看你第二段代码的逻辑:
for sub in subs: if sub in clis: print(sub)
当第一个sub(['xxxx5201727'])执行if sub in clis时,Python会把clis这个迭代器从头到尾遍历一遍,检查是否有匹配项。这次遍历直接把clis的所有内容都取完了,后面的sub再执行if sub in clis时,clis已经是空的了,自然找不到任何匹配。而且之后的for cli in clis循环也不会输出任何内容,因为迭代器已经耗尽。
而你第一段代码能正常输出,是因为先遍历subs,再遍历clis,这时候clis还没被访问过,所以能正常输出所有内容。
解决方案:将迭代器转为可重复访问的列表
解决方法很简单,先把clis的内容转换成列表,这样就可以多次访问了。另外,你的CSV每行只有一个元素,csv.reader会把每行包装成单元素列表(比如['xxxx181000']),我们可以直接提取字符串,让判断更直观。
修改后的代码(符合你的需求:打印subs中不存在于cli的元素)
import csv # 读取cli.csv并转为字符串列表 with open('cli.csv', 'rb') as clisFile: clis_reader = csv.reader(clisFile, delimiter=' ', quotechar='|') # 提取每行的第一个元素(因为每行只有一个值) clis_list = [row[0] for row in clis_reader] # 读取subsToBeCleaned.csv并判断 with open('subsToBeCleaned.csv', 'rb') as subsFile: subs_reader = csv.reader(subsFile, delimiter=' ', quotechar='|') for row in subs_reader: sub = row[0] if sub not in clis_list: print(sub) print "----" # 可以重复访问clis_list for cli in clis_list: print(cli)
更简化的版本(因为你的CSV没有复杂分隔符,直接读行即可)
如果你的CSV文件每行就是一个纯字符串,没有逗号、空格等分隔符,完全可以不用csv模块,直接读取每行并去掉换行符,效率更高:
# 读取cli.csv,去掉每行的换行符,用集合判断更快 with open('cli.csv', 'rb') as f: clis_set = {line.strip() for line in f if line.strip()} # 读取subsToBeCleaned.csv并判断 with open('subsToBeCleaned.csv', 'rb') as f: for line in f: sub = line.strip() if sub and sub not in clis_set: print(sub) print "----" for cli in clis_set: print(cli)
这里用集合clis_set代替列表,是因为集合的成员判断速度比列表快,数据量大的时候优势更明显。
输出验证
修改后的代码会输出:
xxxx5201727 xxxx5205685 ---- xxxx181000 xxxx181001 xxxx181002 xxxx181003 xxxx181004
完全符合你想要的:打印subsToBeCleaned.csv中不存在于cli.csv的元素。
内容的提问来源于stack exchange,提问作者Florin COJOCARU
相关产品推荐
相关产品推荐

