如何在Python3中将列表写入带换行的文件
我正在尝试用Python 3把一个数组(列表?)写入一个文本文件。目前我有:
def save_to_file(*text):
with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
for lines in text:
print(lines, file = myfile)
myfile.close
这段代码把数组的内容直接写进了文本文件,也就是说,
['element1', 'element2', 'element3']
username@machine:/path$
我想要的效果是创建一个文件,里面的内容是
element1
element2
element3
username@machine:/path$
我试过不同的方法来循环遍历数组并添加一个换行符"\n",但似乎写入操作一次性把整个数组都写进去了。这个问题和如何将字符串列表写入文件并添加换行符?类似,但那里的语法看起来是Python 2的?当我尝试修改后:
def save_to_file(*text):
myfile = open('/path/to/filename.txt', mode='wt', encoding='utf-8')
for lines in text:
myfile.write(lines)
myfile.close
...Python的命令行给出了“TypeError: must be str, not list”的错误,我觉得这是因为Python 2和Python 3之间的变化。我缺少什么才能让每个元素都换行呢?
编辑:感谢@agf和@arafangion;结合你们两位的建议,我想出了:
def save_to_file(text):
with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
myfile.write('\n'.join(text))
myfile.write('\n')
看起来我之前的问题部分出在"*text"上(我之前读过这个可以展开参数,但直到你们提到[element]变成了[[element]]时我才明白我遇到了字符串和列表的类型错误;我一直以为我需要告诉定义它接收的是一个列表/数组,而只是写“test”会被当作字符串)。一旦我把它改成只用text,并用myfile.write和join结合,额外的\n就能在文件末尾加上最后一个换行符了。
相关问题:
4 个回答
通过使用“f”字符串,可以将列表中的每个项目写入文本文件的新行中。
my_list=['a', 'b', 'c']
with open('/path/to/filename.txt', mode='w', encoding='utf-8') as myfile:
for item in my_list:
myfile.write(f"\n{item}")
输出结果:
a
b
c
这里面有很多错误。
- 你的缩进搞乱了。
- 在save_to_file中,'text'这个属性指的是所有的参数,而不仅仅是某一个特定的参数。
- 你使用的是“文本模式”,这会让人困惑。应该使用二进制模式,这样'\n'的含义就会一致且明确。
当你在“文本中的行”上进行迭代时,由于这些错误,实际上你是在遍历函数中的所有参数,因为'text'代表了你所有的参数。这就是'*'的作用。(至少在这种情况下是这样。严格来说,它是遍历所有剩余的参数——请查看文档了解更多信息)。
[['element1', 'element2', 'element3']]
把myfile.close去掉,特别是在你使用with的时候。因为with会自动帮你关闭myfile,而且如果不使用with的话,你调用close也得像close()这样写,才能起作用。在Python 3中,建议你总是使用with。
with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
myfile.write('\n'.join(lines))
不要用print来写文件,应该用file.write。在这种情况下,你想写几行中间有换行符,所以可以用'\n'.join(lines)把这些行连接起来,然后直接把生成的字符串写入文件。
如果lines里的元素不是字符串,试着:
myfile.write('\n'.join(str(line) for line in lines))
先把它们转换成字符串。
你的第二个版本不工作是因为另一个原因。如果你传入
['element1', 'element2', 'element3']
它会变成
def save_to_file(*text):
因为*会把每个参数放到一个列表里,即使你传入的已经是一个列表。
如果你想支持传入多个列表,并且依然一个接一个地写入,可以这样做:
def save_to_file(*text):
with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
for lines in text:
myfile.write('\n'.join(str(line) for line in lines))
myfile.write('\n')
或者,如果只传一个列表,就去掉*,按照我上面说的做。
补充: @Arafangion说得对,写文件的时候你应该用b而不是t。这样,你就不用担心不同平台处理换行符的方式不一样。