有没有办法简化这一点;“n路合并”;用python

有没有办法简化这一点;“n路合并”;用python,python,algorithm,sorting,mergesort,Python,Algorithm,Sorting,Mergesort,现在我已经硬编码了4条if/elif/else语句。有没有更具活力的方法?例如,如果我想进行10路或40路合并 #4-way merge sort, sorted page files outfile="fullsorted.txt" of=open(outfile,"w") f1=open("temp0-sorted.txt","r") f2=open("temp1-sorted.txt","r") f3=open("temp2-sorted.txt","r") f4=open("temp3-

现在我已经硬编码了4条if/elif/else语句。有没有更具活力的方法?例如,如果我想进行10路或40路合并

#4-way merge sort, sorted page files
outfile="fullsorted.txt"
of=open(outfile,"w")
f1=open("temp0-sorted.txt","r")
f2=open("temp1-sorted.txt","r")
f3=open("temp2-sorted.txt","r")
f4=open("temp3-sorted.txt","r")

f1_line=f1.readline()
f2_line=f2.readline()
f3_line=f3.readline()
f4_line=f4.readline()

while len(f1_line)>0 and len(f2_line)>0 and len(f3_line)>0 and len(f4_line)>0:
  if f1_line < f2_line and f1_line < f3_line and f1_line < f4_line and len(f1_line)>0:
    of.write(f1_line)
    f1_line=f1.readline()
  elif f2_line < f3_line and f1_line < f4_line and len(f2_line)>0:
    of.write(f2_line)
    f2_line=f2.readline()
  elif f3_line < f4_line and len(f3_line)>0:
    of.write(f3_line)
    f3_line=f3.readline()
  else:
    of.write(f4_line)
    f4_line=f4.readline()

of.close()
#4路合并排序,已排序页面文件
outfile=“fullsorted.txt”
of=打开(输出文件,“w”)
f1=打开(“temp0 sorted.txt”、“r”)
f2=打开(“temp1 sorted.txt”,“r”)
f3=打开(“temp2 sorted.txt”、“r”)
f4=打开(“temp3 sorted.txt”、“r”)
f1_line=f1.readline()
f2_line=f2.readline()
f3_line=f3.readline()
f4_line=f4.readline()
而len(f1_线)>0和len(f2_线)>0和len(f3_线)>0和len(f4_线)>0:
如果f1_线0:
of.write(f1\U行)
f1_line=f1.readline()
elif f2_线0:
of.write(f2_行)
f2_line=f2.readline()
elif f3_线0:
of.write(f3_行)
f3_line=f3.readline()
其他:
of.write(f4_行)
f4_line=f4.readline()
of.close()

使用您自己的代码模式,将其扩展为基于列表的方法,如下所示:

outfile="fullsorted.txt"
of=open(outfile,"w")
files = ["temp0-sorted.txt", "temp1-sorted.txt","temp2-sorted.txt","temp3-sorted.txt"]

filehandles = [open(f, "r") for f in files]

lines = [f.readline() for f in filehandles]

while len(filehandles) > 0:
    smallest = min(lines)
    smallestposition = lines.index(smallest)
    of.write(smallest)
    lines[smallestposition] = filehandles[smallestposition].readline()
    if lines[smallestposition] == "":
        filehandles[smallestposition].close()
        filehandles.pop(smallestposition)
        lines.pop(smallestposition)

of.close()
请注意,这将合并整个文件,而不是在一个文件用完时立即停止。

只需使用:


谢谢大家提供的提示,以下是我的解决方案:

sorted_files=[]

strings=[]
for i in xrange(files+1):
  sorted_files.append(open("temp"+str(i)+"-sorted.txt","r"))
  strings.append(sorted_files[i].readline())

print len(sorted_files)
print strings
eofs=0
while eofs != 1:
  small_str=min(filter(lambda x: x != "", strings))
  str_index=strings.index(small_str)
  of.write(small_str)
  strings[str_index]=sorted_files[str_index].readline()
  if all(i =="" for i in strings):
    eofs=1
作为一个基准测试,我在一个大约650万行(~700MB)的文件中进行了测试,将其分页为500000行文件,然后按照字典顺序对其进行快速排序,并对具有上述代码的文件进行排序合并(其实就是合并),因此合并了大约128个文件,(我有一个20亿行的文件,但在删除页面文件时意外删除了它),它对文件进行了排序,并在16分钟内找到了重复的文件:

real    15m54.375s
user    15m52.096s
sys 0m3.000s

这是我的第一个这样的脚本,如果你能给我一些反馈,比如页面大小合适,使用的排序方法正确,我会非常高兴。页面文件生成和排序很快,但是合并的时间最多。

首先,想象一个列表:
l=[f1,f2,f3…]
@DSM:不需要现代Python;
heapq.merge
从2.6开始就存在了。@ShadowRanger:啊,你说得对!那么从简化的角度来说,这可能是最好的。我正在尝试在没有内置合并功能的情况下实现它,不过谢谢你的提示(而且文件太大,内存不够,所以我一次只能读取一行)@TomFranks:
heapq.merge
是一个生成器函数(惰性地读取输入,惰性地写入输入;它的编写方式与您的代码尝试执行的操作惊人地相似),和
writelines
写得很慢,因此内存不是问题。您可以轻松地试验不同的页面大小,并自己发布详细信息。将其与使用内置heapq.merge的运行进行单独比较也很有用。我怀疑在内存中执行临时分页(StringIO)将产生最大的好处。只需运行一次分析并查看结果。为什么要让其他人推测您自己可以轻松确定机器上的结果:)我现在可以做有限的测试,也就是说,我只有一个大文件大小。而且#2,可能有更好的方法来编码它以提高效率,因为我说过这是我的第一个程序。下面是结果:一个有6400万字符串的文件的结果:*500000行页面文件(128个文件)=15分钟46秒*1000000行页面文件(64个文件)=11分钟19秒*2500000行页面文件(26个文件)=8分钟28秒*8000000行页面文件(8个文件)=7分钟49秒*16000000行页面文件(4个文件)=7分钟58秒
real    15m54.375s
user    15m52.096s
sys 0m3.000s