Запис списку у файл із Python


673

Це найчистіший спосіб написати список у файл, оскільки writelines()він не вставляє символи нового рядка?

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

Здається, був би стандартний спосіб ...


37
Зверніть увагу, що writelinesне додає нові рядки, тому що вони дзеркально readlines, що також не видаляє їх.
SingleNegationElimination

Відповіді:


910

Ви можете використовувати цикл:

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
Це не так вже й складно, але чому б просто не використовувати соління або json, щоб не турбуватися про серіалізацію та десеріалізацію?
Джейсон Бейкер

82
Наприклад, тому що ви хочете вихідний текстовий файл, який можна легко читати, редагувати тощо з одним елементом у рядку. Навряд чи рідкісне бажання ;-).
Алекс Мартеллі

1
Я виявив, що \ n у першому було надлишковим на Python 2.7 / Windows
Хорхе Родрігес

11
Це напише додатковий символ нового рядка в кінці ... замість циклу, ви можете просто написатиthefile.write('\n'.join(thelist))
Tgsmith61591

3
Я додам: "Будьте обережні з типом даних списку". Я отримував якісь дивні результати, можливо, це може комусь допомогти:thefile.write(str(item) + "\n")
iipr

383

Що ти будеш робити з файлом? Чи існує цей файл для людей чи інших програм із чіткими вимогами щодо сумісності?

Якщо ви просто намагаєтеся серіалізувати список на диск для подальшого використання тим самим додатком python, вам слід перебрати цей список.

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 - outfile - це щось на кшталт: open( "save.p", "wb" ) infile - це щось на кшталт:open( "save.p", "rb" )
xxjjnn

2
Проблема полягає в тому, що список повинен вміщуватися в пам'яті. Якщо це не так, лінія за рядком дійсно є можливою стратегією (інакше йде з якоюсь альтернативою, як у stackoverflow.com/questions/7180212/… )
Filippo Mazza

1
У Python 2 використовуйте 'r' замість 'rb' під час читання соління, якщо ви отримуєте "ValueError: невпевнений маринований рядок"
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
Звичайно, перше питання, яке виникає на увазі, полягає в тому, чи потрібно ОП, щоб він закінчився новим рядком і чи має значення кількість місця? Ви знаєте, що вони говорять про передчасні оптимізації.
Джейсон Бейкер

15
Недолік: Це створює весь вміст для файлу в пам'яті перед тим, як записати будь-який з них, тому пікове використання пам'яті може бути високим.
RobM

4
Я ніколи не можу змусити це працювати. Я отримую цю помилку: "text = '\ n'.join (найменування) +' \ n 'TypeError: пункт послідовності 0: очікувана рядок, список знайдено"
День

2
Ви повинні переконатися, що всі елементи в 'nameelist' є рядками.
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))

Це незалежно від платформи. Він також завершує завершальний рядок символом нової лінії, що є найкращою практикою UNIX .

Починаючи з Python 3.6, "{}\n".format(item)можна замінити F-рядки: f"{item}\n".


я не хочу додати "\ n" для останнього елемента, що робити? не хочу, якщо умова
під

4
@pyd Замініть петлю для циклу на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]

Це корисно, оскільки синтаксис є пітонічним, він читається людиною, і його можна читати іншими програмами іншими мовами.


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 до ~ 100 Мб 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 (тестовий список); #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

В загальному

Далі йде синтаксис методу написки ()

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_writlines.htm




7

Ви також можете використовувати функцію друку, якщо ви перебуваєте на python3 наступним чином.

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

це не лише один рядок у myfile.txt, такий як: ['a', 'b', 'c'] замість того, щоб у кожному рядку писати а, b, c.
Гаррі Дуонг


2

Ця логіка спочатку перетворить елементи в списку в string(str). Іноді в списку міститься такий кортеж

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

Ця логіка буде писати, щоб подати кожен кортеж у новий рядок. Пізніше ми можемо використовувати evalпід час завантаження кожного кортежу при читанні файлу:

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

Ще один спосіб ітерації та додавання нового рядка:

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

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залежно від вашої потреби.


-2

У Python3 ви можете використовувати цю петлю

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

-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 () вважає fi ле '' t'ext 'і відкриває його в режимі' r'ead. У нашому прикладі ми вперше відкриваємо файл у текстовому режимі запису та використовуємо метод запису objectлевого об'єкта для запису у файл та потім остаточно закриваємо файл.

Наведений вище приклад - із книги "Байт Пітона" Swaroop C H. swaroopch.com


5
Це записує рядок у файл, а не в список (рядків), як просить ОП
gwideman
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.