Python Writelines不使用换行符写入行,只填充文件
我有一个将列表写入文件的程序。 该列表是管道分隔线的列表,这些线应按如下方式写入文件:Python Writelines不使用换行符写入行,只填充文件,python,Python,我有一个将列表写入文件的程序。 该列表是管道分隔线的列表,这些线应按如下方式写入文件: 123|GSV|Weather_Mean|hello|joe|43.45 122|GEV|temp_Mean|hello|joe|23.45 124|GSI|Weather_Mean|hello|Mike|47.45 但它给他们写了这样一行啊哈: 123|GSV|Weather_Mean|hello|joe|43.45122|GEV|temp_Mean|hello|joe|23.45124|GSI|Weat
123|GSV|Weather_Mean|hello|joe|43.45
122|GEV|temp_Mean|hello|joe|23.45
124|GSI|Weather_Mean|hello|Mike|47.45
但它给他们写了这样一行啊哈:
123|GSV|Weather_Mean|hello|joe|43.45122|GEV|temp_Mean|hello|joe|23.45124|GSI|Weather_Mean|hello|Mike|47.45
该程序将所有行写入一行,没有任何换行符。。这让我很伤心,我必须想办法扭转这种局面,但不管怎样,我的程序哪里出了问题?我认为写行应该把行写在文件上,而不是把所有的东西都写在一行上
fr = open(sys.argv[1], 'r') # source file
fw = open(sys.argv[2]+"/masked_"+sys.argv[1], 'w') # Target Directory Location
for line in fr:
line = line.strip()
if line == "":
continue
columns = line.strip().split('|')
if columns[0].find("@") > 1:
looking_for = columns[0] # this is what we need to search
else:
looking_for = "Dummy@dummy.com"
if looking_for in d:
# by default, iterating over a dictionary will return keys
new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
else:
new_idx = str(len(d)+1)
d[looking_for] = new_idx
kv = open(sys.argv[3], 'a')
kv.write(looking_for+" "+new_idx+'\n')
kv.close()
new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
fw.writelines(line_list)
各国:
writelines()
不添加行分隔符
因此,您需要自己添加它们。例如:
line_list.append(new_line + "\n")
每当您将一个新项目添加到
line\u列表中时,对于Python新手来说,这实际上是一个非常常见的问题,尤其是在标准库和流行的第三方库中,一些读取函数去掉了换行符,但几乎没有任何写入函数(除了与log
相关的东西)添加它们
因此,有很多Python代码可以执行以下操作:
fw.write('\n'.join(line_list) + '\n')
或
任何一个都是正确的,当然,你甚至可以用换行符函数来编写你自己的WriteLines来完成它
但你只有在无法避免的情况下才应该这样做
如果你能像Greg Hewgill的建议那样首先创建/保留新行,那就更好了:
line_list.append(new_line + "\n")
如果你能在比原始文本行更高的层次上工作,那就更好了,比如像esuaro建议的那样,使用标准库中的模块
例如,在定义fw
之后,您可以执行以下操作:
cw = csv.writer(fw, delimiter='|')
然后,与此相反:
new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
fw.writelines(line_list)
您可以这样做:
row_list.append(d[looking_for] + columns[1:])
cw.writerows(row_list)
最后,与此相反:
new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
fw.writelines(line_list)
您可以这样做:
row_list.append(d[looking_for] + columns[1:])
cw.writerows(row_list)
最后,您的设计是“打开一个文件,然后建立一个要添加到文件的行列表,然后一次写入所有行”。如果你要在上面打开文件,为什么不一行一行地写呢?无论您使用的是简单的书写还是csv.writer
,它都会使您的生活更简单,代码更易于阅读。(有时一次编写一个文件可能有简单、高效或正确的理由,但一旦您将打开的从写入一直移动到程序的另一端,您几乎一次就失去了所有好处。)写线()
不添加行分隔符。您可以通过使用map()
在每个字符串的末尾添加新的\n
(换行符)来更改字符串列表
items = ['abc', '123', '!@#']
items = map(lambda x: x + '\n', items)
w.writelines(items)
正如其他人所提到的,与方法名称的含义相反,writelines
不添加行分隔符。这是一个发电机的教科书案例。下面是一个人为的例子:
def item_generator(things):
for item in things:
yield item
yield '\n'
def write_things_to_file(things):
with open('path_to_file.txt', 'wb') as f:
f.writelines(item_generator(things))
优点:显式添加新行,而无需修改输入或输出值或进行任何混乱的字符串连接。而且,至关重要的是,不会在内存中创建任何新的数据结构。IO(写入文件)是指这种事情实际上很重要的时候。希望这对别人有帮助 正如其他人所指出的,writelines
是一个用词不当的词(它可笑地没有在每行末尾添加换行符)
为此,请将其显式添加到每行:
with open(dst_filename, 'w') as f:
f.writelines(s + '\n' for s in lines)
正如我们在这里所确定的,writelines
不会为您添加换行符。但是,每个人似乎都缺少的是,当它被用作readlines()
的直接“对应物”时,它不必这样做,而且最初的读取会保留新行
当您以二进制模式(通过'rb'
)打开文件进行读取时,请使用readlines()
将文件内容提取到内存中,并按行分割,换行符仍附着在行的末尾!因此,如果您随后将它们写回,您可能不希望writelines
附加任何内容
因此,如果您执行以下操作:
with open('test.txt','rb') as f: lines=f.readlines()
with open('test.txt','wb') as f: f.writelines(lines)
您应该得到与开始时相同的文件内容。因为我们只想分隔行,而python中的writelines
函数不支持在行之间添加分隔符,因此我编写了以下最适合此问题的简单代码:
sep = "\n" # defining the separator
new_lines = sep.join(lines) # lines as an iterator containing line strings
最后:
with open("file_name", 'w') as file:
file.writelines(new_lines)
你完成了。归功于布伦特·浮士德
Python>=3.6,带格式字符串:
with open(dst_filename, 'w') as f:
f.writelines(f'{s}\n' for s in lines)
行
可以是集
如果你是老派(和我一样),你可以在第二行下面添加f.write('\n')
。你似乎没有在行列表中的任何地方添加“\n”
。你可以看看我在哪里添加“\n”?是否将其添加到列表对象???+1。这是最简单的解决方案,如果OP不想切换到更高的级别,如csv
,几乎可以肯定这是最合适的。仅仅为了“匹配”,函数的名称就太糟糕了readlines.bether-than糟糕的名称:糟糕的功能所有这一切都是因为python在writelines
Wow中没有明显的作用。对于Python来说,这是一种荒谬的行为:readlines()应该去掉换行符,但不会,writelines()应该添加换行符,但不会。拥有读线和写线的全部意义在于,您可以轻松地读写列表。有点恼火!像f.writelines(lines,end='\n')这样的PEP值吗?在第二个示例中,应该是fw.writelines(line+'\n'表示line in line_list)在第二个示例中,什么时候您希望读取一个文件以将其写回?您对代码示例的理解太过字面化了。我并没有包括一个虚假的上下文和无关的示例代码,当您读取一个文件并将其写回时。在这两者之间通常会有一些东西,您可以在其中修改内容。或者,您可能正在将源文件“复制”/调整为目标文件。重点是读/写行的对应方会隐式地处理这个问题。对不起,我不是故意要坚持这个问题。只是大多数时候,当我读一个文件和wri的时候