การเขียนรายการไปยังไฟล์ด้วย Python


674

นี่เป็นวิธีที่สะอาดที่สุดในการเขียนรายการลงในไฟล์เนื่องจากwritelines()ไม่ได้แทรกอักขระบรรทัดใหม่หรือไม่

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

ดูเหมือนว่าจะมีวิธีมาตรฐาน ...


37
โปรดทราบว่าwritelinesจะไม่เพิ่มบรรทัดใหม่เนื่องจากจะสะท้อนreadlinesซึ่งยังไม่ได้ลบออก
เจรจาเดี่ยวสิ้นสุด

คำตอบ:


911

คุณสามารถใช้การวนซ้ำ:

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

ใน Python 2 คุณยังสามารถใช้

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

หากคุณกระตือรือร้นในการเรียกใช้ฟังก์ชั่นเดียวอย่างน้อยก็ลบวงเล็บเหลี่ยม[]ออกเพื่อให้สตริงที่จะพิมพ์ทำทีละครั้ง (genexp มากกว่า listcomp) - ไม่มีเหตุผลที่จะต้องใช้หน่วยความจำทั้งหมด เพื่อทำให้รายการทั้งหมดของสตริงเป็นจริง


7
มันไม่ซับซ้อนอย่างมาก แต่ทำไมไม่เพียงแค่ใช้ดองหรือเจสันเพื่อให้คุณไม่ต้องกังวลเกี่ยวกับการทำให้เป็นอนุกรมและ
เจสันเบเกอร์

82
ตัวอย่างเช่นเนื่องจากคุณต้องการไฟล์ข้อความเอาต์พุตที่สามารถอ่านแก้ไขและอื่น ๆ ได้อย่างง่ายดายด้วยหนึ่งรายการต่อบรรทัด แทบจะไม่ปรารถนา ;-)
Alex Martelli

1
ฉันพบว่า \ n ในอันแรกนั้นซ้ำซ้อนบน Python 2.7 / Windows
Jorge Rodriguez

11
นี้จะเขียนอักขระขึ้นบรรทัดใหม่พิเศษในตอนท้าย ... แทนที่จะวนคุณสามารถเขียนthefile.write('\n'.join(thelist))
Tgsmith61591

3
ฉันจะเพิ่ม: "ระวังชนิดข้อมูลของรายการ" ฉันได้รับผลลัพธ์แปลก ๆ บางทีนี่อาจช่วยใครซักคน:thefile.write(str(item) + "\n")
iipr

383

คุณจะทำอย่างไรกับไฟล์นี้? ไฟล์นี้มีอยู่สำหรับมนุษย์หรือโปรแกรมอื่น ๆ ที่มีข้อกำหนดด้านความสามารถในการทำงานร่วมกันอย่างชัดเจนหรือไม่?

หากคุณเพียงแค่พยายามทำให้เป็นอนุกรมรายการไปยังดิสก์เพื่อใช้ในภายหลังโดยแอพหลามเดียวกันคุณควรจะดองรายการ

import pickle

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

หากต้องการอ่านย้อนกลับ:

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

35
+1 - ทำไมต้องบูรณาการวงล้อใหม่เมื่อ Python มีการทำให้เป็นอนุกรมอยู่ภายใน
เจสันเบเกอร์

20
+1 - ไฟล์ออกมีลักษณะเช่น: open( "save.p", "wb" ) infile เป็นสิ่งที่ต้องการ:open( "save.p", "rb" )
xxjjnn

2
ปัญหาคือรายการจะต้องพอดีกับหน่วยความจำ หากไม่ใช่กรณีนี้การทำทีละบรรทัดเป็นกลยุทธ์ที่เป็นไปได้ (หรืออาจเกิดขึ้นกับทางเลือกบางอย่างในstackoverflow.com/questions/7180212/… )
Filippo Mazza

1
ใน Python 2 ให้ใช้ 'r' แทน 'rb' เมื่ออ่านผักดองถ้าคุณได้รับ "ValueError: string string ที่ไม่ปลอดภัย"
queise

1
@serafeim: ไม่; with:บล็อกจะปิดแฟ้มก่อนที่จะดำเนินการต่อไปข้างนอกคำสั่งต่อไปของwithบล็อก
SingleNegationElimination

286

วิธีที่ง่ายกว่าคือ:

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

คุณสามารถตรวจสอบให้แน่ใจว่ารายการทั้งหมดในรายการเป็นสตริงที่ใช้นิพจน์ตัวสร้าง

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

โปรดจำไว้ว่าitemlistรายการทั้งหมดจะต้องอยู่ในหน่วยความจำดังนั้นโปรดระมัดระวังเกี่ยวกับการใช้หน่วยความจำ


23
ไม่มีการขึ้นบรรทัดใหม่ใช้พื้นที่ 2x เมื่อเทียบกับการวนซ้ำ
เดฟ

7
แน่นอนคำถามแรกที่เกิดขึ้นกับใจคือ OP ต้องการหรือไม่ที่จะสิ้นสุดในการขึ้นบรรทัดใหม่และปริมาณของพื้นที่มีความสำคัญหรือไม่ คุณรู้ว่าสิ่งที่พวกเขาพูดเกี่ยวกับการเพิ่มประสิทธิภาพก่อนวัยอันควร
เจสันเบเกอร์

15
ข้อเสีย: สิ่งนี้จะสร้างเนื้อหาทั้งหมดสำหรับไฟล์ในหน่วยความจำก่อนที่จะเขียนออกมาดังนั้นการใช้หน่วยความจำสูงสุดอาจสูง
RobM

4
ฉันไม่สามารถทำให้มันทำงานได้ ฉันได้รับข้อผิดพลาดนี้: "text = '\ n'.join (namelist) +' \ n 'TypeError: ลำดับรายการ 0: สตริงที่คาดไว้, พบรายการ"
Dan

2
คุณต้องตรวจสอบให้แน่ใจว่าองค์ประกอบทั้งหมดใน 'namelist' เป็นสตริง
osantana

94

ใช้Python 3และPython 2.6+ไวยากรณ์:

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

นี่เป็นแพลตฟอร์มอิสระ นอกจากนี้ยังยุติบรรทัดสุดท้ายด้วยตัวอักษรขึ้นบรรทัดใหม่ซึ่งเป็นระบบปฏิบัติการยูนิกซ์ปฏิบัติที่ดีที่สุด

เริ่มต้นกับงูหลาม 3.6 "{}\n".format(item)สามารถถูกแทนที่ด้วย f"{item}\n"F-สตริง:


ฉันไม่ต้องการเพิ่ม "\ n" สำหรับรายการสุดท้ายจะทำอย่างไร? ไม่ต้องการถ้าเงื่อนไข
pyd

4
@pyd แทนที่ for for loop ด้วยfile_handler.write("\n".join(str(item) for item in the_list))
orluke

88

อีกวิธีหนึ่ง ทำให้เป็นอนุกรมกับ json โดยใช้simplejson (รวมเป็นjsonใน python 2.6):

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

หากคุณตรวจสอบ output.txt:

[1, 2, 3, 4]

สิ่งนี้มีประโยชน์เนื่องจากไวยากรณ์เป็น pythonic สามารถอ่านได้โดยมนุษย์และสามารถอ่านได้โดยโปรแกรมอื่นในภาษาอื่น


39

ฉันคิดว่ามันน่าสนใจที่จะสำรวจประโยชน์ของการใช้ genexp ดังนั้นนี่คือสิ่งที่ฉันใช้

ตัวอย่างในคำถามใช้เครื่องหมายวงเล็บเหลี่ยมเพื่อสร้างรายการชั่วคราวและเทียบเท่ากับ:

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

ซึ่งไม่จำเป็นต้องสร้างรายการชั่วคราวของทุกสายที่จะเขียนออกมานี้อาจใช้จำนวนเงินที่สำคัญของหน่วยความจำขึ้นอยู่กับขนาดของรายการของคุณและวิธีการอย่างละเอียดการส่งออกของที่str(item)มี

วางวงเล็บ (เทียบเท่าลบห่อlist()โทรด้านบน) แทนจะผ่านชั่วคราวกำเนิดเพื่อfile.writelines():

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

เครื่องกำเนิดไฟฟ้านี้จะสร้างการแสดงitemวัตถุของคุณตามต้องการ (เช่นที่เขียนออกมา) นี่เป็นเหตุผลที่ดี:

  • ค่าโสหุ้ยหน่วยความจำมีขนาดเล็กแม้สำหรับรายการที่มีขนาดใหญ่มาก
  • หากstr(item)ช้าแสดงว่าไฟล์มีความคืบหน้าในการดำเนินการแต่ละรายการ

วิธีนี้จะหลีกเลี่ยงปัญหาหน่วยความจำเช่น:

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

(ฉันเรียกใช้ข้อผิดพลาดนี้โดย จำกัด หน่วยความจำเสมือนสูงสุดของ Python ไว้ที่ ~ 100MB ด้วยulimit -v 102400)

ทำให้การใช้งานหน่วยความจำไปด้านใดด้านหนึ่งวิธีนี้ไม่ได้เร็วกว่าเดิมจริง ๆ :

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 บน Linux)


20

เพราะฉันขี้เกียจ ....

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())

รายการ json ต่อเนื่องได้หรือไม่
kRazzy R

1
ใช่แน่นอนพวกเขาเป็น!
CommandoScorch

1
json นำเข้า; test_list = [1,2,3]; list_as_a_string = json.dumps (test_list); #list_as_a_string เป็นสตริง '[1,2,3]'
CommandoScorch

ฉันทำเช่นนี้ with open ('Sp1.txt', 'a') as outfile: json.dump (sp1_segments, outfile) logger.info ("Saved sp_1 segments"); ปัญหาคือโปรแกรมของฉันทำงานสามครั้งและผลลัพธ์ที่ได้จากการดำเนินการสามรายการเริ่มคลอน มีวิธีใดที่จะเพิ่ม 1-2 บรรทัดว่างเพื่อให้ผลลัพธ์จากการทดสอบแต่ละครั้งสามารถมองเห็นได้
kRazzy R

1
แน่นอน! คุณสามารถแทนทำjson.dump(sp1_segments + "\n\n", outfile)?
CommandoScorch

19

เรียงลำดับรายการเป็นไฟล์ข้อความด้วยค่าที่คั่นด้วยจุลภาค

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

14

โดยทั่วไป

ต่อไปนี้เป็นไวยากรณ์สำหรับวิธีwritelines ()

fileObject.writelines( sequence )

ตัวอย่าง

#!/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()

การอ้างอิง

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




7

คุณสามารถใช้ฟังก์ชั่นการพิมพ์ได้หากคุณใช้ python3 ดังนี้

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

ไม่ใช่แค่ใส่หนึ่งบรรทัดใน myfile.txt สิ่งที่ต้องการ: ['a', 'b', 'c'] แทนที่จะเขียน a, b, c ในแต่ละบรรทัด
Harry Duong


2

string(str)ตรรกะนี้เป็นครั้งแรกจะแปลงรายการในรายการ บางครั้งรายการมีสิ่งอันดับเช่น

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

ตรรกะนี้จะเขียนไฟล์แต่ละ tuple ในบรรทัดใหม่ เราสามารถใช้evalในขณะที่โหลดแต่ละ tuple เมื่ออ่านไฟล์:

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

ใน python> 3 คุณสามารถใช้printและ*สำหรับการเอาออกอาร์กิวเมนต์:

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

-2

ให้ avg เป็นรายการจากนั้น:

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

คุณสามารถใช้%eหรือ%sขึ้นอยู่กับความต้องการของคุณ



-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

วิธีการทำงาน: ขั้นแรกให้เปิดไฟล์โดยใช้ฟังก์ชั่นเปิดในตัวและระบุชื่อของไฟล์และโหมดที่เราต้องการเปิดไฟล์ โหมดสามารถเป็นโหมดอ่าน ('r'), โหมดเขียน ('w') หรือโหมดต่อท้าย ('a') นอกจากนี้เรายังสามารถระบุได้ว่าเรากำลังอ่านเขียนหรือต่อท้ายในโหมดข้อความ ('t') หรือโหมดไบนารี ('b') มีโหมดอื่น ๆ อีกมากมายที่พร้อมใช้งานและช่วย (เปิด) จะให้รายละเอียดเพิ่มเติมเกี่ยวกับพวกเขา โดยค่าเริ่มต้น open () จะถือว่าไฟล์เป็น 't'ext fi le และเปิดในโหมด' r'ead ในตัวอย่างของเราเราจะเปิดไฟล์ในโหมดการเขียนข้อความและใช้วิธีการเขียนของวัตถุไฟล์เพื่อเขียนไปยังไฟล์จากนั้นเราจะปิดไฟล์

ตัวอย่างข้างต้นมาจากหนังสือ "A Byte of Python" โดย Swaroop C H. swaroopch.com


5
สิ่งนี้เขียนสตริงไปยังไฟล์ไม่ใช่รายการ (ของสตริง) ตามที่ OP ถาม
gwideman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.