2011-03-22 72 views
0

我有两个文件,称为源和目标。我比较源中的每个元素以检查它是否也存在于目标中。如果它不存在于目标中,我将它打印出来(最终目标是有0的差异)。这是我写的代码。比较Python中的文件内容

 
def finddefaulters(source,target): 
    f = open(source,'r') 
    g = open(target,'r') 

    reference = f.readlines() 
    done = g.readlines() 
    for i in reference: 
    if i not in done: 
     print i, 

我需要

  1. 帮助,这将如何代码在额定1-10
  2. 规模我怎样才能使它更好,最佳,如果文件大小是巨大的。

另一个问题 - 当我将所有行读作列表元素时,它们被解释为'element \ n' - 所以为了正确比较,我必须在每个文件的末尾添加一个换行符。有没有办法去掉换行符,所以我不必在文件末尾添加换行符。我试过rstrip。但它没有奏效。 在此先感谢。

+0

'done = g.readlines()'创建一个列表。 '如果我没有完成'在列表中搜索。多次。看看'set()'。 – eumiro 2011-03-22 14:30:29

+4

您似乎在重新创建[diff](http://docs.python.org/library/difflib.html) – 2011-03-22 14:31:25

+0

除了其他所有内容之外,“f”和“g”对于您的变量来说都是可怕的名称。称他们是明智的。 “我”也可以改进。 – 2011-03-22 14:32:54

回答

2

关于效率:如果双击两个列表的大小显示您的方法具有O(m*n)asymptotic runtime complexity其中mnreferencedone,即元件的数量,该算法将运行4次更长(时间固定的常数,与理论计算机科学家无关)。如果mn非常大,则可能需要选择更快的算法,例如,首先使用.sort()(运行时复杂度:O(n * log(n)))对两个列表进行排序,然后再遍历列表一次(运行时复杂度:O(n))。该算法的运行时间复杂度最差为O(n * log(n)),这已经是一个很大的改进。但是,为了提高效率,您交易代码的可读性和简单性,所以我只会建议您在绝对必要的情况下执行此操作。

关于编码风格:您不需要.close()您应该使用的文件句柄。而不是打开和关闭文件句柄,你可以使用python的with language construct。另外,如果你喜欢的功能的风格,你可以通过一个表的表达式替换for循环:

for i in reference: 
    if i not in done: 
     print i, 

就变成了:

items = [i.strip() for i in reference if i not in done] 
print ' '.join(items) 

不过,这样你将不会看到,而列表中的任何进展正在组成。

由于joaquin已经提到,您可以直接循环使用f而不是f.readlines(),因为文件句柄支持iterator protocol

2

一些想法:

1)使用[with]安全地打开文件:

with open(source) as f: 
    ............. 

with语句用于包装与上下文管理器中定义的方法 的 执行块。这 允许共同尝试...除了...终于 使用模式被封装为 方便重用。

2),你可以在一个文件,而不是使用readlines方法的行迭代:

for line in f: 
    .......... 

3)虽然这一小段它可能是不够的,试图为你的变量使用更翔实的名字。不建议使用单字母名称。

4)如果您想获得python lib的利润,请尝试difflib模块中的函数。例如:

make_file(fromlines, tolines[, fromdesc][, todesc][, context][, numlines]) 

比较fromlines和tolines(列表串 ),并返回一个字符串,它 是含有由线差异 与线间和分子内一个 表,示出线路一个完整的HTML文件突出显示行更改 。

+0

您可以提供带有关键字文档的链接,或者说明它的作用。 – 2011-03-22 14:35:00