Python: создать генератор списка JSON serializable

Как я могу объединить список файлов JSON в огромный массив JSON? У меня 5000 файлов и 550 000 элементов списка.

Моя первая попытка заключалась в использовании jq , но похоже, что jq -s не оптимизирован для большого ввода.

jq -s -r '[.[][]]' *.js 

Эта команда работает, но занимает слишком много времени, и я действительно хотел бы решить эту проблему с помощью Python.

Вот мой текущий код:

 def concatFiles(outName, inFileNames): def listGenerator(): for inName in inFileNames: with open(inName, 'r') as f: for item in json.load(f): yield item with open(outName, 'w') as f: json.dump(listGenerator(), f) 

Я получаю:

 TypeError: <generator object listGenerator at 0x7f94dc2eb3c0> is not JSON serializable 

Любая попытка загрузить все файлы в RAM вызовет OOM-killer Linux. У тебя есть идеи?

3 Solutions collect form web for “Python: создать генератор списка JSON serializable”

Вы должны получить из list и переопределить метод __iter__ .

 import json def gen(): yield 20 yield 30 yield 40 class StreamArray(list): def __iter__(self): return gen() # according to the comment below def __len__(self): return 1 a = [1,2,3] b = StreamArray() print(json.dumps([1,a,b])) 

Результат – [1, [1, 2, 3], [20, 30, 40]] .

Начиная с simplejson 3.8.0, вы можете использовать параметр iterable_as_array чтобы сделать любую итерабельную сериализацию в массив

 # Since simplejson is backwards compatible, you should feel free to import # it as `json` import simplejson as json json.dumps((i*i for i in range(10)), iterable_as_array=True) 

результат [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Основываясь на принятом ответе, вот StreamArray, в который я в конечном итоге пошел. Он содержит две ложь:

  1. Предложение о том, что self.__tail__ может быть неизменным
  2. len(StreamArray(some_gen)) является либо 0, либо 1

,

 import itertools class StreamArray(list): def __init__(self, gen): self.gen = gen def destructure(self): try: return self.__head__, self.__tail__, self.__len__ except AttributeError: try: self.__head__ = self.gen.__next__() self.__tail__ = self.gen self.__len__ = 1 # A lie except StopIteration: self.__head__ = None self.__tail__ = [] self.__len__ = 0 return self.__head__, self.__tail__, self.__len__ def __iter__(self): head, tail, len_ = self.destructure() if len_ > 0: return itertools.chain([head], tail) else: return [].__iter__() def __next__(self): return self.destructure()[0] def __len__(self): return self.destructure()[2] 

Только для одного использования!

  • Создание пользовательского JSONEncoder
  • Python: Bad JSON - Ключи не цитируются
  • Объекты запроса Python не являются сериализуемыми
  • Преобразование django ValuesQuerySet в объект json
  • как удалить объект json с помощью python?
  • python json error: ValueError: Ожидающее значение: строка 1 столбец 1 (char 0)
  • Как исключить определенные поля для сериализации с помощью jsonpickle?
  • Внутренняя ошибка сервера при вводе точек с использованием JSON в InfluxDB
  • Одинарные и двойные кавычки в json-загрузках в Python
  • Django Rest Framework POST вложенные объекты
  • Преобразование объекта динамического python в json
  • Python - лучший язык программирования в мире.