需要更有效的循环嵌套解决方案

时间:2010-03-03 14:17:37

标签: python loops for-loop nested

我正在尝试比较两个文件。我将列出两个文件内容:

 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的新手所以我上面的概念可能存在缺陷。此外,我之前从未使用套装:(。有人可以帮我一把吗?

2 个答案:

答案 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年代出版),从而古怪使用“流程图”(我们说的代码)或算法)和“表格”(我们说的数据或数据结构) - 但一般概念仍然完全有效:数据的组织和性质,在各种专注于数据处理的程序中(如你的),可能比代码的组织更重要,特别是因为它限制了后者; - )。