在 Python 中使用 zip_longest 时,For 循环不插入换行符 3
For-loop not inserting a line break when using zip_longest in Python 3
我正在写一个简单的文本比较工具。它需要两个文本文件——一个模板和一个目标——并使用两个 for 循环比较每一行中的每个字符。任何差异都使用 Unicode 完整块符号 (\u2588) 突出显示。在目标行比模板长的情况下,我使用 itertools.zip_longest 用填充值填充不存在的字符。
from itertools import zip_longest
def compare(filename1, filename2):
file1 = open(filename1, "r")
file2 = open(filename2, "r")
for line1, line2 in zip_longest(file1, file2):
for char1, char2 in zip_longest(line1, line2, fillvalue=None):
if char1 == char2:
print(char2, end='')
elif char1 == None:
print('\u2588', end='')
compare('template.txt', 'target.txt')
Template file: Target file:
First line First lineXX
Second line Second line
Third line Third line
但是,这似乎与 Python 的自动换行位置相混淆。当一行以这样的填充值结束时,不会产生换行符,给出这样的结果:
First line██Second line
Third line
而不是:
First line██
Second line
Third line
在重写脚本以使用 .append 和 .join(为保持简短而未显示)后问题仍然存在,但它允许我突出显示问题:
Result when both files are identical:
['F', 'i', 'r', 's', 't', ' ', 'l', 'i', 'n', 'e', '\n']
First line
['S', 'e', 'c', 'o', 'n', 'd', ' ', 'l', 'i', 'n', 'e', '\n']
Second line
['T', 'h', 'i', 'r', 'd', ' ', 'l', 'i', 'n', 'e']
Third line
Result when first line of target file has two more characters:
['F', 'i', 'r', 's', 't', ' ', 'l', 'i', 'n', 'e', '█', '█']
First line██['S', 'e', 'c', 'o', 'n', 'd', ' ', 'l', 'i', 'n', 'e', '\n']
Second line
['T', 'h', 'i', 'r', 'd', ' ', 'l', 'i', 'n', 'e']
Third line
如您所见,如果行的长度相同,Python 会自动添加一个换行符 \n,但是一旦涉及到 zip_longest,列表中的最后一个字符就是块,而不是换行符。为什么会这样?
在比较字符之前删除你的行并在每行之间打印新行:
from itertools import zip_longest
def compare(filename1, filename2):
file1 = open(filename1, "r")
file2 = open(filename2, "r")
for line1, line2 in zip_longest(file1, file2):
line1, line2 = line1.strip(), line2.strip() # <- HERE
for char1, char2 in zip_longest(line1, line2, fillvalue=None):
if char1 == char2:
print(char2, end='')
elif char1 == None:
print('\u2588', end='')
print() # <- HERE
compare('template.txt', 'target.txt')
我正在写一个简单的文本比较工具。它需要两个文本文件——一个模板和一个目标——并使用两个 for 循环比较每一行中的每个字符。任何差异都使用 Unicode 完整块符号 (\u2588) 突出显示。在目标行比模板长的情况下,我使用 itertools.zip_longest 用填充值填充不存在的字符。
from itertools import zip_longest
def compare(filename1, filename2):
file1 = open(filename1, "r")
file2 = open(filename2, "r")
for line1, line2 in zip_longest(file1, file2):
for char1, char2 in zip_longest(line1, line2, fillvalue=None):
if char1 == char2:
print(char2, end='')
elif char1 == None:
print('\u2588', end='')
compare('template.txt', 'target.txt')
Template file: Target file:
First line First lineXX
Second line Second line
Third line Third line
但是,这似乎与 Python 的自动换行位置相混淆。当一行以这样的填充值结束时,不会产生换行符,给出这样的结果:
First line██Second line
Third line
而不是:
First line██
Second line
Third line
在重写脚本以使用 .append 和 .join(为保持简短而未显示)后问题仍然存在,但它允许我突出显示问题:
Result when both files are identical:
['F', 'i', 'r', 's', 't', ' ', 'l', 'i', 'n', 'e', '\n']
First line
['S', 'e', 'c', 'o', 'n', 'd', ' ', 'l', 'i', 'n', 'e', '\n']
Second line
['T', 'h', 'i', 'r', 'd', ' ', 'l', 'i', 'n', 'e']
Third line
Result when first line of target file has two more characters:
['F', 'i', 'r', 's', 't', ' ', 'l', 'i', 'n', 'e', '█', '█']
First line██['S', 'e', 'c', 'o', 'n', 'd', ' ', 'l', 'i', 'n', 'e', '\n']
Second line
['T', 'h', 'i', 'r', 'd', ' ', 'l', 'i', 'n', 'e']
Third line
如您所见,如果行的长度相同,Python 会自动添加一个换行符 \n,但是一旦涉及到 zip_longest,列表中的最后一个字符就是块,而不是换行符。为什么会这样?
在比较字符之前删除你的行并在每行之间打印新行:
from itertools import zip_longest
def compare(filename1, filename2):
file1 = open(filename1, "r")
file2 = open(filename2, "r")
for line1, line2 in zip_longest(file1, file2):
line1, line2 = line1.strip(), line2.strip() # <- HERE
for char1, char2 in zip_longest(line1, line2, fillvalue=None):
if char1 == char2:
print(char2, end='')
elif char1 == None:
print('\u2588', end='')
print() # <- HERE
compare('template.txt', 'target.txt')