2017-01-03 3 views
0

Я попытался найти этот вопрос с ключевыми словами в вопросе, но не смог найти подходящее решение.Python - Объединение n разных json-файлов/словарей (n может меняться)

Скажем, у меня есть список JSON файлов (предположим, верхний уровень всегда будет словарем):

"../data/Flickr_EXIF_0.json", 
"../data/Flickr_EXIF_150.json", 
"../data/Flickr_EXIF_300.json", 
"../data/Flickr_EXIF_450.json", 

Вопрос заключается в том, чтобы объединить/объединить все файлы JSon в один файл.

Было бы, конечно, просто сделать что дано нам знать, сколько JSON файлы, которые мы объединяем как,

with open("../data/Flickr_EXIF_0.json", "r") as jFl: 
    obj1 = json.load(jFl) 

with open("../data/Flickr_EXIF_150.json", "r") as jFl: 
    obj2 = json.load(jFl) 

with open("../data/Flickr_EXIF_300.json", "r") as jFl: 
    obj3 = json.load(jFl) 

with open("../data/Flickr_EXIF_450.json", "r") as jFl: 
    obj4 = json.load(jFl) 

d = {**obj1, **obj2, **obj3, **obj4} 

Но как бы вы сказали написать функцию, которая может объединить неизвестное количество JSONs , Я ищу питоновское решение.

Это мое частичное решение, которое выдает ошибку:

def appendJSON(*inpFl): 
    flObjs = [] 
    for fl in inpFl: 
     with open(fl, "r") as jFl: 
      flObjs.append(json.load(jFl)) 

    # something smart here! 
    itemsList = [list(objs.items()) for objs in flObjs] 

    return dict(itemsList) 

Ошибка:

ValueError Traceback (most recent call last) in() 20 "../data/Flickr_EXIF_1350.json", 21 "../data/Flickr_EXIF_1500.json", ---> 22 "../data/Flickr_EXIF_1650.json")

in appendJSON(*inpFl) 7 itemsList = [objs.items() for objs in flObjs] 8 ----> 9 return dict(itemsList) 10 11 objs = appendJSON("../data/Flickr_EXIF_0.json",

ValueError: dictionary update sequence element #0 has length 150; 2 is required

Примеры значений отладки для itemsList:

[[('5822864395', 
    {'date': '2010-06-10 14:48:25', 
    'height': 2592, 
    'lat': 0.0, 
    'long': 0.0, 
    'orientation': 0, 
    'width': 2818}), 
    ('1458886548', 
    {'date': '2007-09-22 02:59:20', 
    'height': 768, 
    'lat': 39.145372, 
    'long': -84.508981, 
    'orientation': 0, 
    'width': 1024})]] 

Альтернативное решение,

def appendJSON(*inpFl): 
    flObjs = [] 
    for fl in inpFl: 
     with open(fl, "r") as jFl: 
      flObjs.append(json.load(jFl)) 

    for i in range(1,len(flObjs)): 
     flObjs[0].update(flObjs[i]) 

    return flObjs[0] 
+0

Вы собираетесь поделиться с нами ошибкой? –

+0

О, конечно. Извини за это! @DanFarrell –

+1

Спасибо. Почему вы пытаетесь превратить список dicts в dict? Как вы ожидаете, что работать, точно? –

ответ

2

Сначала я хотел бы сделать общее решение, а затем опционально оптимизировать, если типы верхних уровней файла JSON одинаковы (т. весь объект/dict или весь массив/список).

Если у вас есть сочетание типов верхнего уровня после загрузки (dict, list, value), вы все равно не сможете их комбинировать. Вы можете комбинировать их только в том случае, если каждый загруженный данные является dict или каждый загруженный является списком. Если у вас есть комбинация или если у вас есть одно или несколько значений на верхнем уровне, вы не можете комбинировать.

Общий подход заключается в создании пустого списка и .append() данные, нагруженный json.load() к нему, сохраняя при этом иметь, ДИКТ, список или значений:

def combine(json_file_names): 
    combined = [] 
    have_dict = False 
    have_list = False 
    for file_name in json_file_names: 
     data = json.load(file_name) 
     combined.append(data) 
     if isinstance(data, dict): 
      have_dict = True 
     elif isinstance(data, list): 
      have_list = True 
     else: 
      have_list = have_dict = True 

    # if have_list and have_dict have the same value, either there is nothing 
    # loaded or it's a mixed bag. In both cases you can't do anything 
    if have_list == have_dict: 
     return combined 
    if have_list: 
     tmp = [] 
     for elem in combined: 
      tmp.extend(elem) 
    else: # have_dict 
     tmp = {} 
     for elem in combined: 
      tmp.update(elem) 
    return tmp 

Пожалуйста, обратите внимание, что при расчесывании Все- top-level-dicts вы перезаписываете пары ключ-значение из предыдущих загруженных данных.

0

Поскольку json легко конвертируется в Python dict, все, что вам нужно сделать, это прочитать все json-файлы в словарях, слить все словари, конвертировать в json и сохранить их в файл.

+1

Это мог быть комментарий. –

+1

Если вы сохраните список как файл JSON ('json.dump ([1, 2, 3])'), как вы собираетесь «легко преобразовать» это в dict? Вы просто присваиваете списку значение случайного ключа? – Anthon