2017-10-10 86 views
1

我需要帮助连接基于常见字符串的两个文本文件。Python文本文件比较和连接

我的第一个txt文件看起来是这样的:

Hello abc 
Wonders xyz 
World abc 

我的第二个txt文件看起来是这样的:

abc A 
xyz B 
abc C 

我希望我的输出文件是:

Hello abc A 
Wonders xyz B 
World abc C 

我的代码是这样的:

a = open("file1","r") 
b = open("file2","r") 
c = open("output","w") 

for line in b: 
    chk = line.split(" ") 

    for line_new in a: 
    chk_new = line_new.split(" ") 

    if (chk_new[0] == chk[1]): 
     c.write(chk[0]) 
     c.write(chk_new[0]) 
     c.write(chk_new[1]) 

但是,当我使用此代码,我得到的输出:

Hello abc A 
Wonders xyz B 
Hello abc C 

3号线不匹配的情况。我该怎么做才能以正确的方式得到它?

回答

0

恐怕你错了,你的代码不会产生你所说的输出。

部分原因是文件只能被读取一次,不同的是如果将读取光标移回文件的开头(file.seek(0)docs)。

部分原因是第一个文件中行的第二个元素以换行符结尾,因此您正在比较​​与"abc\n"等,这将永远不会是真的。

因此输出文件将是完全空的。

那么你如何解决这个问题呢?不止一次读取文件似乎过于复杂,不要这样做。我建议你做的线沿线的东西:

# open all the files simultaneously 
with open('file1', 'r') as (f1 
), open('file2', 'r') as (f2 
), open('output', 'w') as (outf 
): 
    lines_left = True 

    while lines_left: 
     f1_line = f1.readline().rstrip() 

     # check if there's more to read 
     if len(f1_line) != 0: 

      f1_line_tokens = f1_line.split(' ') 

      # no need to strip the line from the second file 
      f2_line_tokens = f2.readline().split(' ') 

      if f1_line_tokens[1] == f2_line_tokens[0]: 
       outf.write(f1_line + ' ' + f2_line_tokens[1]) 
     else: 
      lines_left = False 

我测试过它在你的例子输入,产生正确的输出(其中文件1是第一个示例文件和file2是第二个)。如果我们谈论巨大的文件(数百万行),这个版本将比aarons更快。在其他情况下,性能差异可以忽略不计。

0

open流不安全,您只能读取一次文件。这样做:

aLines = [] 
bLines = [] 

with open("file1","r") as a: 
    for line in a: 
     aLines.append(line.strip().split(" ")) 

with open("file2","r") as b: 
    for line in b: 
     bLines.append(line.strip().split(" ")) 

bLines.reverse() 

with open("output","w") as c: 
    for chk in aLines: 
     chk_new = bLines.pop() 
     if chk_new[0] == chk[1]: 
      c.write(chk[0]) 
      c.write(chk_new[0]) 
      c.write(chk_new[1]) 
+0

感谢您的意见。但我担心的是,字符串匹配会从工作表的开始处获取值,因为第一个实例正在第一行中。 – user8753436

+0

所以现在我试图将文本文件转换为字典元素。感谢您的反馈意见 :) – user8753436