gzip список вложенных словарей - PullRequest
0 голосов
/ 02 мая 2020

У меня есть группа .jsonl.gz файлов. Я могу прочитать их, используя скрипт:

 import json
 import gzip
 with gzip.open(filepath, "r") as read_file:  # file path ends with .jsonl.gz
     try:
         # read gzip file which contains a list of json files (json lines)
         # each json file is a dictionary of nested dictionaries
         json_list = list(read_file)
     except:
         print("fail to read thezip ")

Затем я выполняю некоторую обработку и получаю некоторые файлы. json и сохраняю их в списке.

for num, json_file in enumerate(json_list):        
        try:
            j_file = json.loads(json_file)
            (...some code...)
        except:
           print("fail")

My вопрос как правильно снова записать их в .jsonl.gz?

Это моя попытка

jsonfilename = 'valid_' +str(num)+'.jsonl.gz'
with gzip.open(jsonfilename, 'wb') as f:
     for dict in list_of_nested_dictionaries:
         content.append(json.dumps(dict).encode('utf-8'))
     f.write(content)

Но я получил эту ошибку: TypeError: memoryview: a bytes-like object is required, not 'list'

Затем я попытался просто сжать список словарей как есть:

jsonfilename = 'valid_' +str(num)+'.jsonl.gz'
with gzip.open(jsonfilename, 'wb') as f:
    f.write(json.dumps(list_of_nested_dictionaries).encode('utf-8'))

Но проблема здесь в том, что он сжал весь список как один блок, и когда я прочитал его обратно, я получил один элемент это весь сохраненный список, но не список json файлов, как я получил с первого шага.

это код, который я использую для чтения

with gzip.open('valid_3.jsonl.gz', "r" , ) as read_file:
    try:
        json_list = list(read_file) # read zip file
        print(len(json_list))# I got 1 here
    except:
        print("fail")
json_list[0].decode('utf-8')

Ответы [ 2 ]

0 голосов
/ 02 мая 2020

решение просто так

     with gzip.open(jsonfilename, 'wb') as f:
     for dict in list_of_nested_dictionaries:
         content.append((json.dumps(dict)+'\n').encode('utf-8'))
     f.writelines(content)
0 голосов
/ 02 мая 2020

f.write(content) принимает байтовую строку, но вы передаете ей список байтовых строк.

f.writelines(content) будет перебирать и записывать каждую байтовую строку из списка.

Редактировать: кстати, gzip предназначен для сжатия одного файла. Если вам нужно сжать несколько файлов в один, я предлагаю сначала упаковать их в tarball , а затем распаковать.

...