Как преобразовать списки в json в python?

#python #json #list #dictionary #nested

#python #json #Список #словарь #вложенный

Вопрос:

Требуемый вывод моих вложенных циклов — json, как туда добраться?

Структура входного списка выглядит как list = [[имя, версия, идентификатор],[имя, версия, идентификатор], …]

 list_1 = [
['mipl-abnd','v1.0.2','eelp234'],
['mipl-avfd','v1.1.5','32fv423'],
['mipl-awsd','v9.0.2','234eelp'],
['mipl-tgfd','v3.0.0','124fdge'],
['mipl-hrdss','v1.0.2','543rfd3'],
['mipl-oldss','v1.0.2','eelp234']] 

list_2 = [
['mipl-abnd','v1.0.2','eelp234'],
['mipl-avfd','v1.1.6','3254323'],
['mipl-awsd','v9.0.2','234eelp'],
['mipl-tgfd','v3.0.0','124fdge'],
['mipl-hrdss','v1.0.2','543rfd3'],
['mipl-newss','v1.0.2','eelp234']] 
  

Это код, который я использовал для получения окончательного списка:

 def get_difference(l1,l2):
    l1 = get_ordered_list(file1.read())     
    l2 = get_ordered_list(file2.read()) 

    d1 = {k:[v1,v2] for k,v1,v2 in l1}
    d2 = {k:[v1,v2] for k,v1,v2 in l2}
    result = []
    for k,v in d2.items():
        if k in d1:
            v1 = d1[k]
            if v1[0] != v[0]:
                result.append({k,v1[0],v[0], v1[1],v[1]})
        else:
            result.append({k,'new',v[0],'new', v[1]})

    for k,v in d1.items():
        if k not in d2:
            result.append({k,v[0],'deprecated', v[1], 'deprecated'})
    
    res_json = json.dumps(result)
    return res_json
  

Текущий вывод :

 result = [['mipl-avfd', 'v1.1.5', 'v1.1.6','32fv423', '3254323'], ['mipl-oldss','v1.0.2', 'deprecated','eelp234', 'deprecated'], ['mipl-newss', 'new','v1.0.2','new', 'eelp234']]
  

Требуемый вывод (я хочу записать его в легко читаемый JSON, который позже можно превратить в таблицу) :

 {diff = {"name" : "mipl-avfd", 
         "old-version" : "v1.1.5", 
         "new-version" : "v1.1.6",
         "old-id" : "32fv423",
         "new-id" : "3254323"
         }, 
         {"name" : "mipl-oldss", 
         "old-version" : "v1.0.2", 
         "new-version" : "deprecated",
         "old-id" : "eelp234",
         "new-id" : "deprecated"
         },
         {"name" : "mipl-newss", 
         "old-version" : "new", 
         "new-version" : "v1.0.2",
         "old-id" : "eelp234",
         "new-id" : "new"
         }

}
  

Комментарии:

1. {k,v1[0],v[0], v1[1],v[1]} и все подобные конструкции создают наборы , а не словари

Ответ №1:

Надеюсь, я правильно понял ваш вопрос. У вас есть «старый» list_1 и «новый» list_2 , и вы хотите создать плоский список, как меняются версии (я полагаю, у list_1 вас старые версии):

 import json
from itertools import groupby


list_1 = [
['mipl-abnd','v1.0.2','eelp234'],
['mipl-avfd','v1.1.5','32fv423'],
['mipl-awsd','v9.0.2','234eelp'],
['mipl-tgfd','v3.0.0','124fdge'],
['mipl-hrdss','v1.0.2','543rfd3'],
['mipl-oldss','v1.0.2','eelp234']]

list_2 = [
['mipl-abnd','v1.0.2','eelp234'],
['mipl-avfd','v1.1.6','3254323'],
['mipl-awsd','v9.0.2','234eelp'],
['mipl-tgfd','v3.0.0','124fdge'],
['mipl-hrdss','v1.0.2','543rfd3'],
['mipl-newss','v1.0.2','eelp234']]


s = sorted(list_1   list_2, key=lambda k: k[0])

out = []
for v, g in groupby(s, lambda k: k[0]):
    g = list(g)
    if len(g) == 2:
        out.append({
            'name': v,
            'old-version': g[0][1],
            'new-version': g[1][1],
            'old-id': g[0][2],
            'new-id': g[1][2],
        })
    else:
        if g[0] in list_1:
            out.append({
                'name': v,
                'old-version': g[0][1],
                'new-version': 'deprecated',
                'old-id': g[0][2],
                'new-id': 'deprecated',
            })
        else:
            out.append({
                'name': v,
                'old-version': 'new',
                'new-version': g[0][1],
                'old-id': 'new',
                'new-id': g[0][2],
            })

print(json.dumps(out, indent=4))
  

С принтами:

 [
    {
        "name": "mipl-abnd",
        "old-version": "v1.0.2",
        "new-version": "v1.0.2",
        "old-id": "eelp234",
        "new-id": "eelp234"
    },
    {
        "name": "mipl-avfd",
        "old-version": "v1.1.5",
        "new-version": "v1.1.6",
        "old-id": "32fv423",
        "new-id": "3254323"
    },
    {
        "name": "mipl-awsd",
        "old-version": "v9.0.2",
        "new-version": "v9.0.2",
        "old-id": "234eelp",
        "new-id": "234eelp"
    },
    {
        "name": "mipl-hrdss",
        "old-version": "v1.0.2",
        "new-version": "v1.0.2",
        "old-id": "543rfd3",
        "new-id": "543rfd3"
    },
    {
        "name": "mipl-newss",
        "old-version": "new",
        "new-version": "v1.0.2",
        "old-id": "new",
        "new-id": "eelp234"
    },
    {
        "name": "mipl-oldss",
        "old-version": "v1.0.2",
        "new-version": "deprecated",
        "old-id": "eelp234",
        "new-id": "deprecated"
    },
    {
        "name": "mipl-tgfd",
        "old-version": "v3.0.0",
        "new-version": "v3.0.0",
        "old-id": "124fdge",
        "new-id": "124fdge"
    }
]
  

Ответ №2:

  1. То, что вы сказали, что json не является допустимым json. Кроме того, json — это строка — вам нужна структура dict. Вам не нужно помещать его в строку json.
  2. Почему вы указываете l1 и l2 в качестве аргументов функции, когда перезаписываете их в первых строках?
  3. file1 и file2 не определены в функции. Кроме того, для чтения файлов вы должны использовать with , чтобы правильно закрыть файл.

Во-первых, вам нужно где-то объявить ключи (метки):

 keys = ["name", "old-version", "old-id", "new-id"]
  

Затем, вместо добавления списка, вы добавляете dict .

К счастью, dicts можно легко создавать из списков кортежей — и мы можем легко объединять ключи и ваши текущие списки в списки кортежей, например:

 dict(zip(keys, [k,v1[0],v[0], v1[1],v[1]]))
  

Итак, теперь это выглядит так:

     for k,v in d2.items():
        if k in d1:
            v1 = d1[k]
            if v1[0] != v[0]:
                result.append(dict(zip(keys, [k,v1[0],v[0], v1[1],v[1]])))
        else:
            result.append(dict(zip(keys, [k,'new',v[0],'new', v[1]])))
    for k,v in d1.items():
        if k not in d2:
            result.append(dict(zip(keys, [k,v[0],'deprecated', v[1], 'deprecated'])))