问题描述
我有file.txt:
textaaa 1
textbbb
textaaa 2
textbbb
textaaa 3
textbbb
我想通过首先读取文件并尝试写入该行来将数组(cc)中的值添加到特定行中:
cc = [10,9,8]
with open("file.txt","r") as in_file:
buf = in_file.readlines()
with open("file.txt","w") as out_file:
for line in buf:
if line == "textbbb\n":
for item in cc:
line = line + "textccc %d\r" % (item)
out_file.write(line)
但是,我得到的是:
textaaa 1
textbbb
textccc 10
textccc 9
textccc 8
textaaa 2
textbbb
textccc 10
textccc 9
textccc 8
textaaa 3
textbbb
textccc 10
textccc 9
textccc 8
我想要的是:
textaaa 1
textbbb
textccc 10
textaaa 2
textbbb
textccc 9
textaaa 3
textbbb
textccc 8
我认为问题出在最后一个for循环中。有什么建议可以解决这个问题吗?
解决方法
您需要对列表进行子集化,而不是遍历列表: 现在,您正在执行此操作:
for line in buf: #for each line of text
if line == "textbbb\n": # if there's a match...
for item in cc: # write a newline for each item in my list..
[...]
out_file.write(line)
因此,您的清单在每次比赛中都会被完全覆盖。一种简单快捷的写单个项目的方法是:
offset = 0
for line in buf:
if line == "textbbb\n":
line = line + "textccc %d\r" % (cc[offset])
offset+=1
out_file.write(line)
编辑:另外,请注意,如果文件的最后一行与您的“ textbbb”模式匹配,此解决方案将不可避免地出错,因为这次将没有结尾行('\ n')字符。
,每次找到textbbb
时都不需要遍历所有列表。使用计数器并在每次肯定检查后将其递增就足够了:
cc = [10,9,8]
with open("file.txt","r") as in_file:
buf = in_file.readlines()
with open("file.txt","w") as out_file:
i = 0
for line in buf:
if line == "textbbb\n":
line = line + "textccc %d\r" % (cc[i])
i += 1
out_file.write(line)
输出:
textaaa 1
textbbb
textccc 10
textaaa 2
textbbb
textccc 9
textaaa 3
textbbb
请注意,未添加最后一行(textccc 8
),因为最后一行是textbbb
,而不是textbbb\n
您不想每次都遍历整个列表,而是每次都使用下一项。您可以使用计数器(请参阅其他答案)。此处显示的替代方法是使用iter
进行迭代,然后在需要下一个值时在该迭代器上调用next
:
cc = [10,"r") as in_file:
buf = in_file.readlines()
iterator = iter(cc)
with open("file.txt","w") as out_file:
for line in buf:
if line == "textbbb\n":
item = next(iterator)
line = line + f"textccc {item}\n"
out_file.write(line)
如果您的cc
列表的长度小于"textbbb"
的出现次数,那么您将以一种或另一种形式获得异常。 (在这种情况下,它将是StopIteration
,但是如果您使用计数器和列表索引,则它将是IndexError
。)
还请注意使用f字符串进行输出格式化。现在已不建议在代码中使用%
进行字符串格式化。