输入t1
P95P,71655,LINC-JP,致病
P95P,71655,LINC-JP,致病
P71P,71655,LINC-JP,致病
P71P,71655,LINC-JP,致病
输出操作
P95P,71655,LINC-JP,致病
P71P,71655,LINC-JP,致病
mycode的
def dup():
fi=open("op","a")
l=[];final="";
q=[];dic={};
for i in open("t1"):
k=i.split(",")
q.append(k[1])
q.append(k[0])
if q in l:
pass
else:
final= final + i.strip() + "\n"
fi.write(str(i.strip()))
fi.write("\n")
l.append(q)
q=[]
#print i.strip()
fi.close()
return final.strip()
d=dup()
在上面的输入行1,2和行3,4是重复的。因此,在输出中删除了这些重复项,输入文件中的条目大约为10 ^ 7。
为什么我的代码自24小时后运行以输入76Mb文件。它还没有完成整个输入文件的一次迭代。它适用于小文件。
任何人都可以指出这么长时间的原因。我如何优化我的程序?
日Thnx
答案 0 :(得分:6)
您正在使用O(n 2 )算法,该算法对较大的文件进行缩放:
for i in open("t1"): # linear pass of file takes O(n) time
...
if q in l: # linear pass of list l takes O(n) time
...
...
如果重复项始终彼此相邻,您应该考虑使用set(即使l
和set
)或itertools.groupby
。这些方法将是O(n)。
答案 1 :(得分:5)
如果您可以访问Unix系统,uniq
是一个很好的实用程序,可以解决您的问题。
uniq input.txt output.txt
请参阅https://www.cs.duke.edu/csl/docs/unix_course/intro-89.html
我知道这是一个Python
问题,但有时Python
不是该任务的工具。
并且您始终可以在python脚本中嵌入系统调用。
答案 2 :(得分:2)
目前尚不清楚为什么要构建一个巨大的字符串(final
)来保存与文件相同的内容,或dic
的内容。就性能而言,如果x in y
为y
而非set
为y
,则可以更快地查找list
。还有一个小问题;较短的变量名称不会提高性能,因此请使用好的名称。我建议:
def deduplicate(infile, outfile):
seen = set()
#final = []
with open(outfile, "a") as out, open(infile) as in_:
for line in in_:
check = tuple(line.split(",")[:2])
if check not in seen:
#final.append(line.strip())
out.write(line) # why 'strip' the '\n' then 'write' a new one?
seen.add(check)
#return "\n".join(final)
如果确实需要final,请将其列为最后一刻(请参阅注释掉的行) - 渐进式字符串连接意味着创建大量不必要的对象。
答案 3 :(得分:1)
有些事情你做得非常低效。最大的一点是您将l
列为一个列表,因此行if q in l
必须搜索列表中的所有内容,以便检查q是否与之匹配。如果你创建la set,则可以使用哈希计算和数组查找来完成成员资格检查,无论你添加多少集合都会花费相同的(小)时间(尽管它会导致{{ 1}}不按照它的写入顺序阅读。
您可以做的其他小加速包括:
l
代替(k[1], k[0])
的列表。q
。您的操作系统将尝试批量处理写入操作,但最后只需执行一次大写操作可能会更快。我不确定这一点,但试试吧。