Menulis daftar ke file dengan Python

675

Apakah ini cara paling bersih untuk menulis daftar ke file, karena writelines()tidak memasukkan karakter baris baru?

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

Sepertinya akan ada cara standar ...

Josh Arenberg
sumber
37
perhatikan bahwa writelinestidak menambahkan baris baru karena itu mirror readlines, yang juga tidak menghapusnya.
SingleNegationElimination

Jawaban:

914

Anda dapat menggunakan loop:

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

Di Python 2, Anda juga bisa menggunakan

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

Jika Anda tertarik pada panggilan fungsi tunggal, setidaknya hapus tanda kurung siku [], sehingga string yang akan dicetak dibuat satu per satu (genexp daripada listcomp) - tidak ada alasan untuk mengambil semua memori yang diperlukan untuk mewujudkan seluruh daftar string.

Alex Martelli
sumber
7
Ini tidak terlalu rumit, tetapi mengapa tidak hanya menggunakan acar atau json sehingga Anda tidak perlu khawatir tentang serialisasi dan deserialisasi?
Jason Baker
82
Misalnya karena Anda menginginkan file teks keluaran yang dapat dengan mudah dibaca, diedit, dll, dengan satu item per baris. Hasrat yang jarang ;-).
Alex Martelli
1
Saya menemukan bahwa \ n pada yang pertama berlebihan pada Python 2.7 / Windows
Jorge Rodriguez
11
Ini akan menulis karakter baris baru ekstra di akhir ... daripada loop, Anda bisa menulisthefile.write('\n'.join(thelist))
Tgsmith61591
3
Saya akan menambahkan: "Hati-hati dengan datatype daftar". Saya mendapatkan beberapa hasil yang aneh, mungkin ini dapat membantu seseorang:thefile.write(str(item) + "\n")
iipr
384

Apa yang akan kamu lakukan dengan file itu? Apakah file ini ada untuk manusia, atau program lain dengan persyaratan interoperabilitas yang jelas?

Jika Anda hanya mencoba membuat serial daftar untuk disk untuk digunakan nanti oleh aplikasi python yang sama, Anda harus memilih acar daftar.

import pickle

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

Untuk membacanya kembali:

with open ('outfile', 'rb') as fp:
    itemlist = pickle.load(fp)
SingleNegationElimination
sumber
35
+1 - Mengapa menemukan kembali roda ketika Python memiliki serialisasi?
Jason Baker
20
+1 - outfile adalah sesuatu seperti: open( "save.p", "wb" ) infile adalah sesuatu seperti:open( "save.p", "rb" )
xxjjnn
2
Masalahnya adalah bahwa daftar tersebut harus sesuai dengan memori. Jika ini bukan masalahnya, baris demi baris memang strategi yang memungkinkan (atau menggunakan beberapa alternatif seperti di stackoverflow.com/questions/7180212/… )
Filippo Mazza
1
Dalam Python 2 gunakan 'r' bukan 'rb' saat membaca acar jika Anda mendapatkan "ValueError: insecure string acar"
queise
1
@serafeim: tidak; yang with:blok akan menutup file sebelum melanjutkan ke pernyataan luar berikutnya dari withblok.
SingleNegationElimination
286

Cara yang lebih sederhana adalah:

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

Anda dapat memastikan bahwa semua item dalam daftar item adalah string menggunakan ekspresi generator:

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

Ingat bahwa semua itemlistdaftar harus dalam memori, jadi, berhati-hatilah dengan konsumsi memori.

osantana
sumber
23
Tidak ada baris baru, menggunakan ruang 2x dibandingkan dengan loop
Dave
7
Tentu saja pertanyaan pertama yang muncul dalam pikiran adalah apakah OP membutuhkannya untuk berakhir pada baris baru dan apakah jumlah ruang penting atau tidak. Anda tahu apa yang mereka katakan tentang optimisasi prematur.
Jason Baker
15
Kelemahan: Ini membangun seluruh konten untuk file dalam memori sebelum menuliskannya, sehingga penggunaan memori puncak mungkin tinggi.
RobM
4
Saya tidak pernah bisa melakukan ini. Saya mendapatkan kesalahan ini: "text = '\ n'.join (daftar nama) +' \ n 'TypeError: item urutan 0: string yang diharapkan, daftar ditemukan"
Dan
2
Anda harus memastikan bahwa semua elemen di 'daftar nama' adalah string.
osantana
94

Menggunakan sintaks Python 3 dan Python 2.6+ :

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

Ini adalah platform-independen. Ini juga mengakhiri baris terakhir dengan karakter baris baru, yang merupakan praktik terbaik UNIX .

Dimulai dengan Python 3.6, "{}\n".format(item)bisa diganti dengan f-string: f"{item}\n".

orluke
sumber
saya tidak ingin menambahkan "\ n" untuk item terakhir, apa yang harus dilakukan? dont want if condition
pyd
4
@ pyd Ganti loop for denganfile_handler.write("\n".join(str(item) for item in the_list))
orluke
88

Namun cara lain. Serialize to json menggunakan simplejson (termasuk json di python 2.6):

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

Jika Anda memeriksa output.txt:

[1, 2, 3, 4]

Ini berguna karena sintaksisnya adalah pythonic, dapat dibaca oleh manusia, dan dapat dibaca oleh program lain dalam bahasa lain.

Jason Baker
sumber
39

Saya pikir akan menarik untuk mengeksplorasi manfaat menggunakan genexp, jadi inilah pendapat saya.

Contoh dalam pertanyaan menggunakan tanda kurung siku untuk membuat daftar sementara, dan itu sama dengan:

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

Yang tidak perlu membangun daftar sementara dari semua baris yang akan ditulis, ini dapat mengkonsumsi sejumlah besar memori tergantung pada ukuran daftar Anda dan bagaimana verbose output str(item)adalah.

Jatuhkan tanda kurung (setara dengan menghapus list()panggilan pembungkus di atas) sebagai gantinya akan meneruskan generator sementara ke file.writelines():

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

Generator ini akan membuat representasi itemobjek Anda yang diakhiri baris baru sesuai permintaan (yaitu, saat dituliskan). Ini bagus karena beberapa alasan:

  • Overhead memori kecil, bahkan untuk daftar yang sangat besar
  • Jika str(item)lambat ada kemajuan yang terlihat dalam file karena setiap item diproses

Ini menghindari masalah memori, seperti:

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

(Saya memicu kesalahan ini dengan membatasi memori virtual maksimum Python hingga ~ 100MB dengan ulimit -v 102400).

Menempatkan penggunaan memori di satu sisi, metode ini sebenarnya tidak lebih cepat dari aslinya:

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 di Linux)

RobM
sumber
20

Karena aku malas ....

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())
CommandoScorch
sumber
Apakah daftar json dapat diubah serial?
kRazzy R
1
Ya, benar!
CommandoScorch
1
impor json; test_list = [1,2,3]; list_as_a_string = json.dumps (test_list); #list_as_a_string sekarang adalah string '[1,2,3]'
CommandoScorch
Saya melakukan ini with open ('Sp1.txt', 'a') as outfile: json.dump (sp1_segments, outfile) logger.info ("Saved sp_1 segments"); Masalahnya adalah program saya berjalan tiga kali, dan hasil dari tiga kali berjalan semakin dihaluskan. apakah ada cara untuk menambahkan 1-2 baris kosong sehingga hasil dari setiap proses dapat dilihat?
kRazzy R
1
Benar! Bisakah Anda melakukannya json.dump(sp1_segments + "\n\n", outfile)?
CommandoScorch
19

Serialize list menjadi file teks dengan nilai dipisahkan koma

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

Secara umum

Berikut ini adalah sintaks untuk metode writelines ()

fileObject.writelines( sequence )

Contoh

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

Referensi

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

Marvin W
sumber
13
file.write('\n'.join(list))
mtasic85
sumber
1
Orang harus mencatat bahwa ini akan mengharuskan file dibuka sebagai teks agar benar-benar netral dari platform.
Jason Baker
2
Bagaimana Anda mendapatkan filevariabel?
Jonathan Morales Vélez
8
with open ("test.txt","w")as fp:
   for line in list12:
       fp.write(line+"\n")
shankar
sumber
7

Anda juga dapat menggunakan fungsi cetak jika Anda menggunakan python3 sebagai berikut.

f = open("myfile.txt","wb")
print(mylist, file=f)
Nandita Damaraju
sumber
bukan hanya menempatkan satu baris di myfile.txt, sesuatu seperti: ['a', 'b', 'c'] alih-alih menulis masing-masing a, b, c pada setiap baris.
Harry Duong
3

Kenapa kamu tidak mencoba

file.write(str(list))
Bob
sumber
2

Logika ini pertama-tama akan mengonversi item dalam daftar menjadi string(str). Terkadang daftar berisi tuple like

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

Logika ini akan menulis untuk mengajukan setiap tuple di baris baru. Kita nanti dapat menggunakan evalsaat memuat setiap tuple saat membaca file:

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 
Tahir Ahmad
sumber
1

Cara lain untuk mengulang dan menambahkan baris baru:

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

Dalam python> 3 Anda dapat menggunakan printdan *untuk membongkar argumen:

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

Biarkan avg menjadi daftar, lalu:

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

Anda dapat menggunakan %eatau %stergantung pada kebutuhan Anda.

belthazar
sumber
-2

Di Python3 Anda bisa menggunakan loop ini

with open('your_file.txt', 'w') as f:
    for item in list:
        f.print("", item)
Nikhil B
sumber
-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

Cara Bekerja: Pertama, buka fi le dengan menggunakan fungsi terbuka built-in dan tentukan nama fi le dan mode di mana kita ingin membuka fi le. Mode dapat berupa mode baca ('r'), mode tulis ('w') atau mode tambahkan ('a'). Kita juga dapat menentukan apakah kita membaca, menulis, atau menambahkan dalam mode teks ('t') atau mode biner ('b'). Sebenarnya ada lebih banyak mode yang tersedia dan bantuan (terbuka) akan memberi Anda lebih banyak detail tentangnya. Secara default, open () menganggap file tersebut sebagai file 't'ext dan membukanya dalam mode' r'ead. Dalam contoh kita, kita pertama-tama membuka fi le dalam mode teks tulis dan menggunakan metode tulis dari objek fi le untuk menulis ke fi le dan kemudian kita akhirnya menutup fi le.

Contoh di atas adalah dari buku "Byte of Python" oleh Swaroop C H. swaroopch.com

vayah
sumber
5
Ini menulis string ke file, bukan daftar (string) seperti yang diminta OP
gwideman