我正在尝试比较两个文件。我将列出两个文件内容:
File 1 File 2
"d.complex.1" "d.complex.1"
1 4
5 5
48 47
65 21
d.complex.10 d.complex.10
46 5
21 46
109 121
192 192
每个文件中共有2000个d.complex。我试图比较两个文件,但问题是第一个文件中d.complex.1下列出的值必须与第二个文件中的所有2000 d.complex条目一起检查,如果条目不匹配,它们是要打印出来。例如,在上面的文件中,在file1中,d.complex.1中的数字48不存在于file2 d.complex.1中;所以这个号码必须存储在一个列表中(以后打印出来)。然后,必须将相同的d.complex.1与file2的d.complex.10进行比较,由于不存在1,48和65,因此必须将它们附加到列表中。
我选择实现此目的的方法是使用集合然后进行交集。我写的代码是:
first_complex=open( "file1.txt", "r" )
first_complex_lines=first_complex.readlines()
first_complex_lines=map( string.strip, first_complex_lines )
first_complex.close()
second_complex=open( "file2.txt", "r" )
second_complex_lines=second_complex.readlines()
second_complex_lines=map( string.strip, second_complex_lines )
second_complex.close()
list_1=[]
list_2=[]
res_1=[]
for line in first_complex_lines:
if line.startswith( "d.complex" ):
res_1.append( [] )
res_1[-1].append( line )
res_2=[]
for line in second_complex_lines:
if line.startswith( "d.complex" ):
res_2.append( [] )
res_2[-1].append( line )
h=len( res_1 )
k=len( res_2 )
for i in res_1:
for j in res_2:
print i[0]
print j[0]
target_set=set ( i )
target_set_1=set( j )
for s in target_set:
if s not in target_set_1:
print s
上面的代码给出了这样的输出(只是一个例子):
1
48
65
d.complex.1.dssp
d.complex.1.dssp
46
21
109 d.complex.1.dssp d.complex.1.dssp d.complex.10.dssp
虽然上面的答案是正确的,但我想要一种更有效的方式来做到这一点,任何人都可以帮助我吗?还打印了两个d.complex.1.dssp而不是一个也不好的。
我想要的是:
d.complex.1
d.complex.1 (name from file2)
1
48
65
d.complex.1
d.complex.10 (name from file2)
1
48
65
我是python的新手所以我上面的概念可能存在缺陷。此外,我之前从未使用套装:(。有人可以帮我一把吗?
答案 0 :(得分:1)
指针:
我对您的输入数据做了一些假设,您可能想尝试这样的事情。
def parsefile(filename):
ret = {}
cur = None
for line in ( x.strip() for x in open(filename,'r')):
if line.startswith('d.complex'):
cur = set()
ret[line] = cur
if not cur or not line.isdigit():
continue
cur.add(int(line))
return ret
def compareStructures(first,second):
# Iterate through key,value pairs in first
for firstcmplx, firstmembers in first.iteritems():
# Iterate through key,value pairs in second
for secondcmplx, secondmembers in second.iteritems():
notinsecond = firstmembers- secondmembers
if notinsecond:
# There are items in first that aren't in second
print firstcmplx
print secondcmplx
print "\n".join([ str(x) for x in notinsecond])
first = parsefile("myFirstFile.txt")
second = parsefile("mySecondFile.txt")
compareStructures(first,second)
编辑修复..显示我依赖运行代码来测试它:)感谢Alex
答案 1 :(得分:1)
@MattH已经有了一个很好的答案,专注于问题的Python细节,虽然它可以在几个细节上得到改进,但改进只会在效率上获得一些百分点 - 值得但不是很好。 / p>
巨大提高效率(与“kai-zen”增量改进相反)的唯一希望是算法的急剧变化 - 根据特征可能会或可能不会实现您未公开的数据,以及有关您的确切要求的一些详细信息。
关键部分是:粗略地说,文件中会出现多少数字,大致是每个“d.complex.N”节有多少个数字?你已经告诉我们每个文件大约有2000个节(当然这也是至关重要的),并且印象是每个文件中它们将按连续增加的N - 1,2,3和等等(是这样吗?)。
你的算法构建了两个map stanza->数字(效率不高,但这就是@MattH的答案集中在增强上)所以那么它不可避免地需要N squared
节到节的检查 - 因为N是2,000,这需要400万次这样的检查。
考虑构建反转地图,数字 - >节 - 如果数字的范围和节中的(数量)的典型大小都是合理限制的,那么它们会更紧凑。例如,如果数字在1到200之间,并且每个节有大约4个数字,则这意味着数字通常在(2000 * 4) / 200
- >中。 40节,所以这样的映射将有200个条目,每个节约40节。它只需要200平方(40,000)的检查,而不是400万,以获得每个数字的联合信息(然后,根据输出格式的确切需要,格式化信息可能需要再次非常大的努力 - 如果你绝对需要最终结果是400万“节对”部分作为输出,那么当然没有办法避免400万“输出操作,这将不可避免地非常昂贵”。
但所有这些都取决于你没有告诉我们的那些数字 - 平均节数,文件中的数字范围,以及你必须绝对尊重输出格式的限制的详细信息(如果数字是合理的,输出格式约束将成为你可以从任何程序中获得的大O性能的关键约束。
请记住,引用Fred Brooks:
告诉我你的流程图并隐瞒 你的桌子,我会继续 神秘莫测。告诉我你的桌子,和 我通常不需要你的流程图; 他们会很明显。
布鲁克斯写于60年代(虽然他的散文集,“神话人月”,后来在70年代出版),从而古怪使用“流程图”(我们说的代码)或算法)和“表格”(我们说的数据或数据结构) - 但一般概念仍然完全有效:数据的组织和性质,在各种专注于数据处理的程序中(如你的),可能比代码的组织更重要,特别是因为它限制了后者; - )。