Python串联/合并一个文件中的一行

时间:2018-09-17 05:24:44

标签: python merge concatenation

我愿意逐行连接两个文件,以便每个文件的每一行连续地合并到第三个文件中。

所以我有以下代码和以下文本文件:

file1.txt
1
3
5
7

file2.txt
2
4
6

代码:

from ast import literal_eval

def merge_lines():
    with open("file1.txt") as f1, open("file2.txt") as f2:
        with open("file3.txt", "r+") as tfile:
            f1_lists = (literal_eval(line) for line in f1)
            f2_lists = (literal_eval(line) for line in f2)
            for l1, l2 in zip(f1_lists, f2_lists):
                tfile.write(str(l1))
                tfile.write("\n")
                tfile.write(str(l2))
                tfile.write("\n")

combine_hands()

这可以正常工作,因为输出文件如下所示:

file3.txt
1
2
3
4
5
6

我的问题是为什么file1.txt的最后一行(数字7)没有合并?

4 个答案:

答案 0 :(得分:3)

由于zip在较短的可迭代项的末尾停止,因此省略了最后一行。

您想要的可能是

from itertools import zip_longest
def merge_lines():
    with open("file1.txt") as f1,\
         open("file2.txt") as f2,\
         open("file3.txt", "w") as tfile:
        for l1, l2 in zip_longest(f1, f2, fillvalue="Empty line"):
            # Or you can place a sentinel value for `fillvalue` 
            # and check it and don't write to file when you see it.                
            tfile.write(l1.strip() + "\n")
            tfile.write(l2.strip() + "\n")

或者如果您不想写出空白行

for l1, l2 in zip_longest(f1, f2, fillvalue=None):
    if l1:                           
        tfile.write(l1)
    if l2:
        tfile.write(l2)

并且由于fillvalue的默认值为None,我们可以将其进一步简化为

for l1, l2 in zip_longest(f1, f2):
    if l1:                           
        tfile.write(l1)
    if l2:
        tfile.write(l2)

编辑

在阅读@DYZ的评论和回答后进行了以下更改:

  1. 修复了多行“打开”语法错误。不幸的是我们不能 使用括号将多行“ with”语句分组。
  2. 添加了第二个选项来检查前哨值(我已经确定了该值) 在我的原始答案中提到)。

答案 1 :(得分:2)

使用函数zip_longest,可以以非常紧凑的方式编写代码:

from itertools import zip_longest
with open("file1.txt") as f1,\
     open("file2.txt") as f2,\
     open("file3.txt", "w") as tfile:
        for l1, l2 in zip_longest(f1, f2, fillvalue=''):
            if l1 != '': tfile.write(l1)
            if l2 != '': tfile.write(l2)

不需要显式读取或类型转换。

答案 2 :(得分:1)

正如其他人提到的,这是因为您使用了普通的zip(),最长列表(文件)的最后一行被省略了.zip只会形成元组,直到最短列表的长度为止

相反,您可以使用以下任一扩展zip来填充最长的列表

    itertools.zip_longest -- in python 3.x +
    itertools.izip_longest  --in python 2.6+

答案 3 :(得分:0)

表达式zip(f1_lists, f2_lists)仅在提供的可迭代对象(在您的情况下为列表)中较短的情况下返回元组列表。 因此,这种行为应按zip documentation进行。

如果要包括最后一行,请尝试使用itertools.ziplongest

from ast import literal_eval
from itertools import ziplongest

def merge_lines():
    with open("file1.txt") as f1, open("file2.txt") as f2:
        with open("file3.txt", "r+") as tfile:
            f1_lists = (literal_eval(line) for line in f1)
            f2_lists = (literal_eval(line) for line in f2)
            for l1, l2 in zip_longest(f1_lists, f2_lists, fillvalue='x'):
                tfile.write(str(l1))
                tfile.write("\n")
                tfile.write(str(l2))
                tfile.write("\n")

combine_hands()