#python #json
Вопрос:
В python я знаю, что могу выгрузить список словарей в файл .json для хранения json.dump()
с json
помощью модуля. Однако, после сброса списка, можно ли добавить больше словарей в этот список в .json
файле без явного чтения, загрузить полный список, добавить, а затем снова сбросить список?
например, у .json
меня есть
[{'a': 1}]
Можно ли добавить {'b', 2}
в список .json
таким образом, чтобы файл стал
[{'a': 1}, {'b', 2}]
Фактический список намного длиннее (порядка десяти миллионов), поэтому мне интересно, есть ли более прямые способы сделать это без чтения всего списка из файла для экономии памяти.
Редактировать:
PS: Я также открыт для другого формата файлов, если он может эффективно хранить большой список словарей и может выполнять описанную выше функцию
Комментарии:
1. Формат JSON для этого не подходит. Взгляните на jsonlines .
2. Что вы подразумеваете под » без явного чтения загрузите полный список, добавьте, а затем снова сбросьте список «? У вас был сохраненный список в файле, и вы не хотите читать этот файл?
3. @Kshitiz Хорошо, я могу прочитать файл, но я пытаюсь избежать чтения всего списка (
json.load()
в переменную, которая может занять большой объем памяти)4. Если бы вы попытались просто открыть файл
notepad
и написать. Извините, но я не уверен, что вы находитесь в Windows или другой операционной системе. Но если файл большой и вы просто хотите добавить только 2/3 вещей, то вы можете попробовать. Я не уверен, что это сработает или нет, поэтому я не публикую это в качестве ответа, пожалуйста, сообщите мне об этом после попытки!
Ответ №1:
Похоже, что при правильных обстоятельствах это может быть простой проблемой с обработкой файлов. Если вы уверены, что корневая структура данных дампа действительно представляет собой массив json, вы можете удалить последнее «]» в файле, а затем добавить в файл новый дамп.
Вы можете добавить его с помощью функции dumps.
from json import dumps, dump
import os
#This represents your current dump call
with open('out.json', 'w') as f:
dump([{'version':1}], f)
# This removes the final ']'
with open('out.json', 'rb ') as f:
f.seek(-1, os.SEEK_END)
f.truncate()
#This appends the new dictionary
with open('out.json', 'a') as f:
f.write(',')
f.write(dumps({'n':1}))
f.write(']')
Похоже, это также работает, если вы сбрасываете данные с отступом, потому что функция сброса в любом случае не заканчивается символом новой строки.
Обработка пустого массива
Если при первом сбросе списка он был пуст, в результате чего в файле «[] «появился пустой массив json, то добавление запятой, как в моем примере, приведет к чему-то вроде» [,…], чего вы, вероятно, не хотите.
То, как я видел, как это обрабатывается в дикой природе протоколами, такими как i3bar (которые используют бесконечный массив json для отправки информации), всегда начинается с элемента заголовка. В их случае они используют { "version": 1 }
.
Поэтому убедитесь, что у вас это есть в начале вашего списка, когда вы делаете первый сброс, то есть, если вы не уверены, что у вас всегда будет что-то в списке.
Другие примечания
Несмотря на то, что такой ручной взлом json используется в таких проектах, как i3bar, я бы лично не рекомендовал делать это в производственной среде.
Ответ №2:
JSON требует, чтобы список был закрыт с помощью a "]"
, поэтому он изначально не является приложением. Вы можете попробовать что-то хитрое, открыв конец файла, удалив»]», а также поработать с новым JSON, который вы пытаетесь написать. Но это грязно.
Интересная особенность JSON заключается в том, что в кодировке нет новых строк. Вы можете довольно легко распечатать JSON, но если вы этого не сделаете, вы можете написать всю запись JSON в одной строке. Итак, вместо списка JSON у вас просто есть куча строк, каждая из которых является кодировкой JSON вашего диктатора.
def append_dict(filename, d):
with open(filename, 'a', encoding='utf-8') as fp:
fp.write(json.dumps(d))
fp.write("n")
def read_list(filename):
with open(filename, encoding='utf-8') as fp:
return [json.loads(line) for line in fp]
Поскольку этот файл теперь представляет собой набор объектов JSON, а не один список JSON, любая программа, ожидающая наличия одного списка в этом файле, потерпит неудачу.
Комментарии:
1. Это хорошее предложение. Может быть, просто упомянуть, что это нарушает совместимость с другими программами, которые ожидают обычный файл json.