Запись списка в файл с помощью Python

676

Это самый чистый способ записи списка в файл, поскольку writelines()не вставляются символы новой строки?

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

Кажется, был бы стандартный путь ...

Джош Аренберг
источник
37
обратите внимание, что writelinesне добавляет новые строки, потому что он отражает readlines, который также не удаляет их.
SingleNegationElimination

Ответы:

915

Вы можете использовать цикл:

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
Это не очень сложно, но почему бы просто не использовать pickle или json, чтобы вам не пришлось беспокоиться о сериализации и десериализации?
Джейсон Бейкер
82
Например, потому что вам нужен выходной текстовый файл, который можно легко читать, редактировать и т. Д., С одним элементом в строке. Вряд ли редкое желание ;-).
Алекс Мартелли
1
Я обнаружил, что \ n в первом из них был избыточен на Python 2.7 / Windows
Хорхе Родригес
11
Это напишет дополнительный символ новой строки в конце ... вместо цикла, вы можете просто написатьthefile.write('\n'.join(thelist))
Tgsmith61591
3
Я бы добавил: «Будьте осторожны с типом списка». Я получал некоторые странные результаты, может быть, это может кому-то помочь:thefile.write(str(item) + "\n")
iipr
384

Что вы собираетесь делать с файлом? Существует ли этот файл для людей или других программ с четкими требованиями к взаимодействию?

Если вы просто пытаетесь сериализовать список на диск для последующего использования тем же приложением Python, вы должны выбрать список.

import pickle

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

Чтобы прочитать это обратно:

with open ('outfile', 'rb') as fp:
    itemlist = pickle.load(fp)
SingleNegationElimination
источник
35
+1 - Зачем изобретать велосипед, если в Python встроена сериализация?
Джейсон Бейкер
20
+1 - outfile - это что-то вроде: open( "save.p", "wb" ) infile - что-то вроде:open( "save.p", "rb" )
xxjjnn
2
Проблема в том, что список должен уместиться в памяти. Если это не так, то строка за строкой действительно является возможной стратегией (или же она использует альтернативу, как в stackoverflow.com/questions/7180212/… )
Филиппо Мазза,
1
В Python 2 используйте «r» вместо «rb» при чтении рассылки, если вы получили «ValueError: небезопасный
перехват
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список должен находиться в памяти, поэтому позаботьтесь об использовании памяти.

osantana
источник
23
Не завершающий перевод строки, использует 2x пробел по сравнению с циклом.
Дейв
7
Конечно, первый вопрос, который приходит на ум, заключается в том, нужно ли OP, чтобы он заканчивался символом новой строки, и имеет ли значение пространство. Вы знаете, что они говорят о преждевременной оптимизации.
Джейсон Бейкер
15
Недостаток: это создает все содержимое файла в памяти перед записью любого из них, поэтому пиковое использование памяти может быть высоким.
RobM
4
Я никогда не смогу заставить это работать. Я получаю эту ошибку: "text = '\ n'.join (namelist) +' \ n 'TypeError: элемент последовательности 0: ожидаемая строка, найден список"
Dan
2
Вы должны убедиться, что все элементы в «namelist» являются строками.
Осантана
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".

orluke
источник
я не хочу добавлять "\ n" для последнего элемента, что делать? не хочу, если условие
Пид
4
@pyd Замените цикл for на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 до ~ 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)

RobM
источник
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())
CommandoScorch
источник
списки 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 ) )
themadmax
источник
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

Марвин В.
источник
13
file.write('\n'.join(list))
mtasic85
источник
1
Следует отметить, что для этого потребуется, чтобы файл был открыт в виде текста, чтобы он был действительно нейтральным к платформе.
Джейсон Бейкер
2
Как вы получаете fileпеременную?
Джонатан Моралес Велес
8
with open ("test.txt","w")as fp:
   for line in list12:
       fp.write(line+"\n")
Шанкар
источник
7

Вы также можете использовать функцию печати, если вы находитесь на python3, следующим образом.

f = open("myfile.txt","wb")
print(mylist, file=f)
Нандита Дамараджу
источник
Разве он не помещает в myfile.txt только одну строку, что-то вроде: ['a', 'b', 'c'] вместо того, чтобы писать a, b, c в каждой строке.
Гарри Дуонг,
3

Почему бы тебе не попробовать

file.write(str(list))
боб
источник
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")
Alex
источник
1

В python> 3 вы можете использовать printи *для распаковки аргументов:

with open("fout.txt", "w") as fout:
    print(*my_list, sep="\n", file=fout)
bricoletc
источник
-2

Позвольте avg быть списком, тогда:

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

Вы можете использовать %eили в %sзависимости от ваших требований.

belthazar
источник
-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'). На самом деле доступно гораздо больше режимов, а help (open) даст вам больше информации о них. По умолчанию open () считает файл «текстовым файлом» и открывает его в режиме «чтения». В нашем примере мы сначала открываем файл в режиме записи текста и используем метод записи объекта файла для записи в файл, а затем окончательно закрываем файл.

Приведенный выше пример взят из книги «Байт Python» Swaroop C H. swaroopch.com

вайах
источник
5
Это записывает строку в файл, а не список (строк), как просит
операционная система