Viết một danh sách vào một tệp bằng Python


672

Đây có phải là cách sạch nhất để viết danh sách vào một tệp, vì writelines()không chèn các ký tự dòng mới?

file.writelines(["%s\n" % item  for item in list])

Có vẻ như sẽ có một cách tiêu chuẩn ...


37
lưu ý rằng writelineskhông thêm dòng mới vì nó phản chiếu readlines, cũng không loại bỏ chúng.
SingleNegationElimination

Câu trả lời:


908

Bạn có thể sử dụng một vòng lặp:

with open('your_file.txt', 'w') as f:
    for item in my_list:
        f.write("%s\n" % item)

Trong Python 2, bạn cũng có thể sử dụng

with open('your_file.txt', 'w') as f:
    for item in my_list:
        print >> f, item

Nếu bạn quan tâm đến một cuộc gọi chức năng, ít nhất hãy xóa dấu ngoặc vuông [], để các chuỗi được in được thực hiện cùng một lúc (một kiểu khai thác thay vì một danh sách) - không có lý do gì để chiếm hết bộ nhớ cần thiết để cụ thể hóa toàn bộ danh sách các chuỗi.


7
Điều này không quá phức tạp, nhưng tại sao không sử dụng dưa chua hoặc json để bạn không phải lo lắng về việc tuần tự hóa và giải tuần tự hóa?
Jason Baker

82
Ví dụ: vì bạn muốn một tệp văn bản đầu ra có thể dễ dàng đọc, chỉnh sửa, v.v., với một mục trên mỗi dòng. Hầu như không phải là một mong muốn hiếm có ;-).
Alex Martelli

1
Tôi thấy rằng \ n trong lần đầu tiên là không cần thiết trên Python 2.7 / Windows
Jorge Rodriguez

11
Điều này sẽ viết thêm một ký tự dòng mới ở cuối ... thay vì vòng lặp, bạn chỉ có thể viếtthefile.write('\n'.join(thelist))
Tgsmith61591

3
Tôi sẽ thêm: "Hãy cẩn thận với kiểu dữ liệu danh sách". Tôi đã nhận được một số kết quả kỳ lạ, có lẽ điều này có thể giúp ai đó:thefile.write(str(item) + "\n")
iipr

383

Bạn sẽ làm gì với tập tin này? Tập tin này có tồn tại cho con người, hoặc các chương trình khác có yêu cầu về khả năng tương tác rõ ràng không?

Nếu bạn chỉ cố gắng tuần tự hóa một danh sách vào đĩa để sử dụng sau cùng bởi cùng một ứng dụng python, bạn nên chọn danh sách đó.

import pickle

with open('outfile', 'wb') as fp:
    pickle.dump(itemlist, fp)

Để đọc lại:

with open ('outfile', 'rb') as fp:
    itemlist = pickle.load(fp)

35
+1 - Tại sao phải phát minh lại bánh xe khi Python được tích hợp sẵn?
Jason Baker

20
+1 - outfile là một cái gì đó như: open( "save.p", "wb" ) infile là một cái gì đó như:open( "save.p", "rb" )
xxjjnn

2
Vấn đề là danh sách phải phù hợp với bộ nhớ. Nếu đây không phải là trường hợp, từng dòng thực sự là một chiến lược khả thi (hoặc nếu không thì sẽ có một số thay thế như trong stackoverflow.com/questions/7180212/ trộm )
Filippo Mazza

1
Trong Python 2, hãy sử dụng 'r' thay vì 'rb' khi đọc dưa chua nếu bạn nhận được "ValueError: chuỗi không an toàn"
xếp hàng

1
@serafeim: không; các with:khối sẽ đóng tập tin trước khi tiếp tục tuyên bố bên ngoài tiếp theo của withkhối.
Độc thân Khuyến khích

285

Cách đơn giản hơn là:

with open("outfile", "w") as outfile:
    outfile.write("\n".join(itemlist))

Bạn có thể đảm bảo rằng tất cả các mục trong danh sách mục là các chuỗi bằng biểu thức trình tạo:

with open("outfile", "w") as outfile:
    outfile.write("\n".join(str(item) for item in itemlist))

Hãy nhớ rằng tất cả các itemlistdanh sách cần phải có trong bộ nhớ, vì vậy, hãy quan tâm đến mức tiêu thụ bộ nhớ.


23
Không có dòng mới, sử dụng không gian gấp 2 lần so với vòng lặp.
Dave

7
Tất nhiên, câu hỏi đầu tiên nảy ra trong đầu là liệu OP có cần nó kết thúc trong một dòng mới hay không và liệu số lượng không gian có quan trọng hay không. Bạn biết những gì họ nói về tối ưu hóa sớm.
Jason Baker

15
Nhược điểm: Điều này xây dựng toàn bộ nội dung cho tệp trong bộ nhớ trước khi ghi bất kỳ nội dung nào ra ngoài, do đó mức sử dụng bộ nhớ tối đa có thể cao.
RobM

4
Tôi không bao giờ có thể làm điều này để làm việc. Tôi gặp lỗi này: "text = '\ n'.join (namelist) +' \ n 'TypeError: chuỗi mục 0: chuỗi dự kiến, danh sách được tìm thấy"
Dan

2
Bạn đã đảm bảo rằng tất cả các thành phần trong 'namelist' là các chuỗi.
osantana

94

Sử dụng cú pháp Python 3Python 2.6+ :

with open(filepath, 'w') as file_handler:
    for item in the_list:
        file_handler.write("{}\n".format(item))

Đây là nền tảng độc lập. Nó cũng chấm dứt dòng cuối cùng với một ký tự dòng mới, đây là cách thực hành tốt nhất của UNIX .

Bắt đầu với Python 3.6, "{}\n".format(item)có thể được thay thế bằng chuỗi f : f"{item}\n".


tôi không muốn thêm "\ n" cho mục cuối cùng, phải làm gì? không muốn nếu có điều kiện
pyd 16/2/18

4
@pyd Thay thế vòng lặp for bằngfile_handler.write("\n".join(str(item) for item in the_list))
orluke

88

Một cách khác. Nối tiếp với json bằng cách sử dụng Simplejson (bao gồm json trong python 2.6):

>>> import simplejson
>>> f = open('output.txt', 'w')
>>> simplejson.dump([1,2,3,4], f)
>>> f.close()

Nếu bạn kiểm tra output.txt:

[1, 2, 3, 4]

Điều này rất hữu ích vì cú pháp là pythonic, nó có thể đọc được và con người có thể đọc được bằng các chương trình khác trong các ngôn ngữ khác.


39

Tôi nghĩ rằng sẽ rất thú vị khi khám phá những lợi ích của việc sử dụng genEx, vì vậy đây là của tôi.

Ví dụ trong câu hỏi sử dụng dấu ngoặc vuông để tạo danh sách tạm thời và do đó tương đương với:

file.writelines( list( "%s\n" % item for item in list ) )

Việc xây dựng một danh sách tạm thời tất cả các dòng sẽ được viết ra một cách không cần thiết, điều này có thể tiêu tốn một lượng bộ nhớ đáng kể tùy thuộc vào kích thước danh sách của bạn và mức độ dài của đầu ra str(item).

Bỏ dấu ngoặc vuông (tương đương với loại bỏ lệnh list()gọi ở trên) thay vào đó sẽ chuyển một trình tạo tạm thời tớifile.writelines() :

file.writelines( "%s\n" % item for item in list )

Trình tạo này sẽ tạo đại diện kết thúc dòng mới của bạn item đối tượng theo yêu cầu (nghĩa là khi chúng được viết ra). Điều này là tốt cho một vài lý do:

  • Chi phí bộ nhớ nhỏ, thậm chí cho các danh sách rất lớn
  • Nếu str(item)chậm, tiến trình có thể nhìn thấy trong tệp khi mỗi mục được xử lý

Điều này tránh các vấn đề về bộ nhớ, chẳng hạn như:

In [1]: import os

In [2]: f = file(os.devnull, "w")

In [3]: %timeit f.writelines( "%s\n" % item for item in xrange(2**20) )
1 loops, best of 3: 385 ms per loop

In [4]: %timeit f.writelines( ["%s\n" % item for item in xrange(2**20)] )
ERROR: Internal Python error in the inspect module.
Below is the traceback from this internal error.

Traceback (most recent call last):
...
MemoryError

(Tôi đã kích hoạt lỗi này bằng cách giới hạn bộ nhớ ảo tối đa của Python xuống ~ 100MB với ulimit -v 102400 ).

Đặt việc sử dụng bộ nhớ sang một bên, phương pháp này thực sự không nhanh hơn so với ban đầu:

In [4]: %timeit f.writelines( "%s\n" % item for item in xrange(2**20) )
1 loops, best of 3: 370 ms per loop

In [5]: %timeit f.writelines( ["%s\n" % item for item in xrange(2**20)] )
1 loops, best of 3: 360 ms per loop

(Python 2.6.2 trên Linux)


20

Bởi vì tôi lười....

import json
a = [1,2,3]
with open('test.txt', 'w') as f:
    f.write(json.dumps(a))

#Now read the file back into a Python list object
with open('test.txt', 'r') as f:
    a = json.loads(f.read())

danh sách json nối tiếp?
kRazzy R

1
Vâng thực sự, họ là!
CommandoScorch

1
nhập khẩu json; test_list = [1,2,3]; list_as_a_opes = json.dumps (test_list); #list_as_a_opes hiện là chuỗi '[1,2,3]'
CommandoScorch

Tôi đang làm điều này with open ('Sp1.txt', 'a') as outfile: json.dump (sp1_segments, outfile) logger.info ("Saved sp_1 segments"); vấn đề là chương trình của tôi chạy ba lần, và kết quả từ ba lần chạy đang bị xáo trộn. Có cách nào để thêm 1-2 dòng trống để kết quả từ mỗi lần chạy là rõ ràng không?
kRazzy R

1
Chắc chắn rồi! thay vào đó bạn có thể làm gì json.dump(sp1_segments + "\n\n", outfile)?
CommandoScorch

19

Sắp xếp danh sách thành tập tin văn bản với giá trị được phân tách bằng dấu phẩy

mylist = dir()
with open('filename.txt','w') as f:
    f.write( ','.join( mylist ) )

14

Nói chung

Sau đây là cú pháp cho phương thức wrlistines ()

fileObject.writelines( sequence )

Thí dụ

#!/usr/bin/python

# Open a file
fo = open("foo.txt", "rw+")
seq = ["This is 6th line\n", "This is 7th line"]

# Write sequence of lines at the end of the file.
line = fo.writelines( seq )

# Close opend file
fo.close()

Tài liệu tham khảo

http://www.tutorialspoint.com/python/file_writelines.htmlm


13
file.write('\n'.join(list))

1
Bạn nên lưu ý rằng điều này sẽ yêu cầu tệp được mở dưới dạng văn bản để thực sự trung lập nền tảng.
Jason Baker

2
Làm thế nào để bạn có được các filebiến?
Jonathan Morales Vélez

8
with open ("test.txt","w")as fp:
   for line in list12:
       fp.write(line+"\n")

7

Bạn cũng có thể sử dụng chức năng in nếu bạn đang dùng python3 như sau.

f = open("myfile.txt","wb")
print(mylist, file=f)

không phải nó chỉ đặt một dòng trong myfile.txt, đại loại như: ['a', 'b', 'c'] thay vì viết mỗi a, b, c trên mỗi dòng.
Harry Dương

3

Tại sao bạn không thử

file.write(str(list))

2

Logic này trước tiên sẽ chuyển đổi các mục trong danh sách thành string(str). Đôi khi danh sách chứa một tuple như

alist = [(i12,tiger), 
(113,lion)]

Logic này sẽ ghi vào tệp mỗi tuple trong một dòng mới. Sau này chúng ta có thể sử dụng evaltrong khi tải từng bộ dữ liệu khi đọc tệp:

outfile = open('outfile.txt', 'w') # open a file in write mode
for item in list_to_persistence:    # iterate over the list items
   outfile.write(str(item) + '\n') # write to the file
outfile.close()   # close the file 

1

Một cách khác để lặp lại và thêm dòng mới:

for item in items:
    filewriter.write(f"{item}" + "\n")

0

Trong python> 3 bạn có thể sử dụng print*để giải nén đối số:

with open("fout.txt", "w") as fout:
    print(*my_list, sep="\n", file=fout)

-2

Trong Python3 Bạn có thể sử dụng vòng lặp này

with open('your_file.txt', 'w') as f:
    for item in list:
        f.print("", item)

-3

Hãy để avg là danh sách, sau đó:

In [29]: a = n.array((avg))
In [31]: a.tofile('avgpoints.dat',sep='\n',dtype = '%f')

Bạn có thể sử dụng %ehoặc %stùy thuộc vào yêu cầu của bạn.


-4
poem = '''\
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!
'''
f = open('poem.txt', 'w') # open for 'w'riting
f.write(poem) # write text to file
f.close() # close the file

Cách thức hoạt động: Trước tiên, hãy mở một bằng cách sử dụng chức năng mở tích hợp và chỉ định tên của fi le và chế độ mà chúng tôi muốn mở le. Chế độ có thể là chế độ đọc ('r'), chế độ ghi ('w') hoặc chế độ chắp thêm ('a'). Chúng tôi cũng có thể chỉ định xem chúng tôi đang đọc, viết hoặc nối thêm ở chế độ văn bản ('t') hay chế độ nhị phân ('b'). Thực tế có nhiều chế độ hơn có sẵn và trợ giúp (mở) sẽ cung cấp cho bạn thêm chi tiết về chúng. Theo mặc định, open () coi fi le là một 't'ext fi le và mở nó ở chế độ' r'ead. Trong ví dụ của chúng tôi, đầu tiên chúng ta mở chế độ ghi văn bản và sử dụng phương thức ghi của đối tượng to le để ghi vào le và sau đó chúng ta sẽ đóng le.

Ví dụ trên là từ cuốn sách "A Byte of Python" của Swaroop C H. swaroopch.com


5
Điều này ghi một chuỗi vào một tệp, không phải là một danh sách (của các chuỗi) như OP yêu cầu
gwideman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.