Writelines在没有换行的情况下写行,只需填写文件即可.

use*_*087 52 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
Run Code Online (Sandbox Code Playgroud)

但它写了这行啊啊啊:

123|GSV|Weather_Mean|hello|joe|43.45122|GEV|temp_Mean|hello|joe|23.45124|GSI|Weather_Mean|hello|Mike|47.45
Run Code Online (Sandbox Code Playgroud)

这个程序把所有的行都写成了一行,没有任何换行符.这给我带来了很大的麻烦,我想弄清楚如何扭转这一点,但无论如何,我的程序错在哪里?我认为写行应该在文件中写下行而不是只写一行到一行.

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)
Run Code Online (Sandbox Code Playgroud)

aba*_*ert 43

这对于Python的新手来说实际上是一个非常普遍的问题 - 特别是因为在标准库和流行的第三方库中,一些读取函数会删除换行符,但几乎没有写入函数(除了log相关的东西)添加它们.

所以,有很多Python代码可以执行以下操作:

fw.write('\n'.join(line_list) + '\n')
Run Code Online (Sandbox Code Playgroud)

要么

fw.write(line + '\n' for line in line_list)
Run Code Online (Sandbox Code Playgroud)

任何一个都是正确的,当然你甚至可以编写自己的writelinesWithNewlines函数来包装它...

但是,如果你无法避免,那么你应该这样做.

如果您可以创建/保留换行符,那就更好了 - 正如Greg Hewgill的建议:

line_list.append(new_line + "\n")
Run Code Online (Sandbox Code Playgroud)

如果你可以在比原始文本行更高的层次上工作,例如,使用标准库中的csv模块,就像esuaro所说的那样,它会更好.

例如,在定义之后fw,您可能会这样做:

cw = csv.writer(fw, delimiter='|')
Run Code Online (Sandbox Code Playgroud)

然后,而不是这个:

new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
Run Code Online (Sandbox Code Playgroud)

你做这个:

row_list.append(d[looking_for] + columns[1:])
Run Code Online (Sandbox Code Playgroud)

最后,而不是这个:

fw.writelines(line_list)
Run Code Online (Sandbox Code Playgroud)

你做这个:

cw.writerows(row_list)
Run Code Online (Sandbox Code Playgroud)

最后,您的设计是"打开一个文件,然后构建一个行列表以添加到文件中,然后立即将它们全部写入".如果你要打开文件顶部,为什么不一个一个地写行?无论您是使用简单的写入还是使用简单的写入csv.writer,它都会让您的生活变得更简单,并且您的代码更易于阅读.(有时可能会有简单,高效或正确的理由一次性写入一个文件 - 但是一旦你将open所有文件一直移动到程序的另一端write,你几乎失去了所有的好处特技的一次.)

  • 所有这一切都是因为python不能用`writelines`做明显的事 (21认同)
  • 哇。在Python方面,这是荒谬的行为:readlines()*应删除*换行符,但不删除,而writelines()*应添加*换行符,但不删除。具有读取行和写入行的全部目的是使您可以轻松地读取和写入列表。轻气! (12认同)
  • 是的,不得不说,这是一个有用的答案,但写行不行……你知道,写单独的行……真是令人头疼。 (8认同)
  • 是否像f.writelines(lines,end ='\ n')这样的PEP值得? (3认同)

Gre*_*ill 40

各州的文件writelines():

writelines() 不添加行分隔符

所以你需要自己添加它们.例如:

    line_list.append(new_line + "\n")
Run Code Online (Sandbox Code Playgroud)

每当你追加一个新项目line_list.

  • 为了"匹配"读取线,这个函数的名字真是太可怕了. (60认同)
  • 比糟糕的名字更糟糕:糟糕的*功能* (8认同)

Bre*_*ust 11

正如其他人所指出的那样,writelines是用词不当(它可笑地不会在每一行的末尾添加换行符).

为此,请使用map:

with open(dst_filename, 'w') as f:
    f.writelines(s + '\n' for s in lines)
Run Code Online (Sandbox Code Playgroud)


qrä*_*bnö 11

致谢Brent Faust


Python >= 3.6,带格式字符串:

with open(dst_filename, 'w') as f:
    f.writelines(f'{s}\n' for s in lines)
Run Code Online (Sandbox Code Playgroud)

lines可以是一个set.

如果您是老派(像我一样),您可以在f.write('\n')第二行下方添加。


Jos*_*ush 8

writelines()不添加行分隔符.您可以通过在每个字符串的末尾map()添加新的\n(换行符)来更改字符串列表.

items = ['abc', '123', '!@#']
items = map(lambda x: x + '\n', items)
w.writelines(items)
Run Code Online (Sandbox Code Playgroud)


jts*_*ven 8

正如其他人所提到的,与方法名称所暗示的相反,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))
Run Code Online (Sandbox Code Playgroud)

优点:显式添加换行符,无需修改输入或输出值或进行任何混乱的字符串连接。而且,最重要的是,不会在内存中创建任何新的数据结构。IO(写入文件)是这类事情真正重要的时候。希望这对某人有帮助!