Zapisywanie listy do pliku za pomocą Pythona

673

Czy to najczystszy sposób na napisanie listy do pliku, ponieważ writelines()nie wstawia znaków nowego wiersza?

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

Wygląda na to, że istniałby standardowy sposób ...

Josh Arenberg
źródło
37
zwróć uwagę, że writelinesnie dodaje nowych wierszy, ponieważ odzwierciedla readlines, co również ich nie usuwa.
SingleNegationElimination

Odpowiedzi:

910

Możesz użyć pętli:

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

W Pythonie 2 możesz także użyć

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

Jeśli zależy Ci na pojedynczym wywołaniu funkcji, usuń przynajmniej nawiasy kwadratowe [], aby napisy były drukowane pojedynczo (genexp zamiast listcomp) - nie ma powodu, aby zajmować całą wymaganą pamięć zmaterializować całą listę ciągów.

Alex Martelli
źródło
7
To nie jest strasznie skomplikowane, ale dlaczego by nie użyć marynaty lub jsona, abyś nie musiał się martwić serializacją i deserializacją?
Jason Baker
82
Na przykład dlatego, że chcesz wyjściowy plik tekstowy, który można łatwo odczytać, edytować itp., Z jednym elementem w wierszu. Raczej rzadkie pragnienie ;-).
Alex Martelli
1
Odkryłem, że \ n w pierwszym z nich był zbędny w Pythonie 2.7 / Windows
Jorge Rodriguez
11
Spowoduje to napisanie dodatkowego znaku nowego wiersza na końcu ... zamiast pętli, możesz po prostu napisaćthefile.write('\n'.join(thelist))
Tgsmith61591
3
Dodałbym: „Uważaj na typ danych listy”. Miałem dziwne wyniki, może to komuś pomóc:thefile.write(str(item) + "\n")
iipr
383

Co zamierzasz zrobić z plikiem? Czy ten plik istnieje dla ludzi lub innych programów z wyraźnymi wymaganiami dotyczącymi interoperacyjności?

Jeśli próbujesz serializować listę na dysk w celu późniejszego wykorzystania przez tę samą aplikację w języku Python, powinieneś wybrać tę listę.

import pickle

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

Aby przeczytać ponownie:

with open ('outfile', 'rb') as fp:
    itemlist = pickle.load(fp)
SingleNegationElimination
źródło
35
+1 - Po co wymyślać koło, gdy Python ma wbudowaną serializację?
Jason Baker
20
+1 - outfile jest coś w stylu: open( "save.p", "wb" ) infile to coś w stylu:open( "save.p", "rb" )
xxjjnn 20.04. Kwietnia
2
Problem polega na tym, że lista musi mieścić się w pamięci. Jeśli tak nie jest, linia po linii jest rzeczywiście możliwą strategią (lub też idzie z jakąś alternatywą, jak w stackoverflow.com/questions/7180212/... )
Filippo Mazza
1
W Pythonie 2 używaj „r” zamiast „rb” podczas czytania marynaty, jeśli otrzymujesz „ValueError: niepewny ciąg marynaty”
kolejka
1
@serafeim: no; with:blok będzie zamknąć plik przed przejściem do następnego rachunku zewnątrz withbloku.
SingleNegationElimination
286

Prostszym sposobem jest:

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

Możesz upewnić się, że wszystkie elementy na liście pozycji są łańcuchami za pomocą wyrażenia generatora:

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

Pamiętaj, że wszystkie itemlistlisty muszą znajdować się w pamięci, więc zadbaj o zużycie pamięci.

osantana
źródło
23
Brak nowej linii, wykorzystuje 2x spację w porównaniu do pętli.
Dave
7
Oczywiście pierwsze pytanie, jakie przychodzi na myśl, brzmi: czy OP musi zakończyć się nową linią i czy ilość miejsca ma znaczenie, czy nie. Wiesz, co mówią o przedwczesnych optymalizacjach.
Jason Baker
15
Wada: konstruuje całą zawartość pliku w pamięci przed zapisaniem któregoś z nich, więc szczytowe użycie pamięci może być wysokie.
RobM
4
Nie mogę tego nigdy uruchomić. Otrzymuję ten błąd: „text = '\ n'.join (lista nazw) +' \ n 'TypeError: element sekwencji 0: oczekiwany ciąg, lista znaleziona”
Dan
2
Musisz upewnić się, że wszystkie elementy w „liście nazw” są ciągami znaków.
osantana,
94

Korzystanie ze składni Python 3 i Python 2.6+ :

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

Jest to niezależne od platformy. Kończy także ostatnią linię znakiem nowej linii, co jest najlepszą praktyką w systemie UNIX .

Począwszy od Pythonie 3.6, "{}\n".format(item)może być zastąpione przez f-wyrażenie: f"{item}\n".

orluke
źródło
nie chcę dodawać „\ n” do ostatniego elementu, co robić? nie chcę, jeśli warunek
pyd
4
@pyd Zamień pętlę for nafile_handler.write("\n".join(str(item) for item in the_list))
orluke
88

Jeszcze inny sposób. Serializuj do json przy użyciu simplejson (dołączony jako json w Pythonie 2.6):

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

Jeśli przejrzysz plik output.txt:

[1, 2, 3, 4]

Jest to przydatne, ponieważ składnia jest pytoniczna, czytelna dla człowieka i może być odczytana przez inne programy w innych językach.

Jason Baker
źródło
39

Pomyślałem, że interesujące byłoby zbadanie korzyści płynących z używania genexp, więc oto moje zdanie.

Przykład w pytaniu używa nawiasów kwadratowych do utworzenia listy tymczasowej, a więc jest równoważny z:

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

Co niepotrzebnie konstruuje tymczasową listę wszystkich wierszy, które zostaną wypisane, może to zużywać znaczną ilość pamięci w zależności od wielkości listy i tego, jak szczegółowe jest wyjście str(item).

Upuszczenie nawiasów kwadratowych (równoważne usunięciu list()powyższego wywołania zawijania ) zamiast tego przekaże tymczasowy generator do file.writelines():

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

Ten generator utworzy itemna żądanie reprezentację twoich obiektów zakończoną znakiem nowej linii (tj. W miarę ich zapisywania). Jest to miłe z kilku powodów:

  • Narzuty pamięci są małe, nawet w przypadku bardzo dużych list
  • Jeśli str(item)jest wolny, widoczny jest postęp w pliku, gdy każdy element jest przetwarzany

Pozwala to uniknąć problemów z pamięcią, takich jak:

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

(Wywołałem ten błąd, ograniczając maksymalną pamięć wirtualną Pythona do ~ 100 MB przy pomocy ulimit -v 102400).

Odkładając zużycie pamięci na bok, ta metoda nie jest wcale szybsza niż oryginał:

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 w systemie Linux)

RobM
źródło
20

Ponieważ jestem leniwy ...

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
źródło
czy listy json można serializować?
kRazzy R
1
Tak, rzeczywiście są!
CommandoScorch
1
import json; test_list = [1,2,3]; list_as_a_string = json.dumps (test_list); #list_as_a_string jest teraz ciągiem „[1,2,3]”
CommandoScorch
Robię to with open ('Sp1.txt', 'a') as outfile: json.dump (sp1_segments, outfile) logger.info ("Saved sp_1 segments"); Problemem jest to, że mój program uruchamia się trzykrotnie, a wyniki z trzech przebiegów są zbierane. czy jest jakiś sposób, aby dodać 1-2 puste wiersze, aby wyniki z każdego przebiegu były widoczne?
kRazzy R
1
Absolutnie! mógłbyś zamiast tego zrobić json.dump(sp1_segments + "\n\n", outfile)?
CommandoScorch,
19

Serializuj listę do pliku tekstowego z oddzieloną przecinkami wartością

mylist = dir()
with open('filename.txt','w') as f:
    f.write( ','.join( mylist ) )
themadmax
źródło
14

Ogólnie

Poniżej znajduje się składnia metody writelines ()

fileObject.writelines( sequence )

Przykład

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

Odniesienie

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

Marvin W.
źródło
13
file.write('\n'.join(list))
mtasic85
źródło
1
Należy zauważyć, że będzie to wymagało otwarcia pliku jako tekstu, aby był naprawdę neutralny dla platformy.
Jason Baker
2
Jak uzyskać filezmienną?
Jonathan Morales Vélez
8
with open ("test.txt","w")as fp:
   for line in list12:
       fp.write(line+"\n")
Shankar
źródło
7

Możesz także użyć funkcji drukowania, jeśli korzystasz z Python3 w następujący sposób.

f = open("myfile.txt","wb")
print(mylist, file=f)
Nandita Damaraju
źródło
czy nie jest to tylko jedna linia w myfile.txt, coś w rodzaju: [„a”, „b”, „c”] zamiast pisania każdego a, b, c w każdej linii.
Harry Duong
3

Dlaczego nie spróbujesz

file.write(str(list))
Kok
źródło
2

Ta logika najpierw przekształci elementy z listy na string(str). Czasami lista zawiera krotkę podobną do

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

Ta logika zapisze w pliku każdą krotkę w nowej linii. Możemy później użyć evalpodczas ładowania każdej krotki podczas czytania pliku:

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
źródło
1

Inny sposób iteracji i dodawania nowej linii:

for item in items:
    filewriter.write(f"{item}" + "\n")
Alex
źródło
1

W pythonie> 3 możesz użyć printi *do rozpakowywania argumentów:

with open("fout.txt", "w") as fout:
    print(*my_list, sep="\n", file=fout)
bricoletc
źródło
-2

W Python3 możesz użyć tej pętli

with open('your_file.txt', 'w') as f:
    for item in list:
        f.print("", item)
Nikhil B.
źródło
-3

Niech avg będzie listą, a następnie:

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

Możesz użyć %elub w %szależności od wymagań.

Belthazar
źródło
-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

Jak to działa: Najpierw otwórz plik, korzystając z wbudowanej funkcji otwierania i określając nazwę pliku oraz tryb, w którym chcemy go otworzyć. Tryb może być trybem odczytu („r”), trybem zapisu („w”) lub trybem dołączania („a”). Możemy również określić, czy czytamy, piszemy, czy dołączamy w trybie tekstowym („t”) lub binarnym („b”). W rzeczywistości dostępnych jest wiele innych trybów, a pomoc (otwarta) da ci więcej szczegółów na ich temat. Domyślnie open () traktuje plik jako plik tekstowy „t” i otwiera go w trybie odczytu. W naszym przykładzie najpierw otwieramy plik w trybie zapisu tekstu i używamy metody write obiektu pliku do zapisu do pliku, a następnie zamykamy go.

Powyższy przykład pochodzi z książki „A Byte of Python” autorstwa Swaroop C. H. swaroopch.com

vayah
źródło
5
Spowoduje to
zapisanie