Как отменить список в словаре в списке? - PullRequest
2 голосов
/ 07 февраля 2020

У меня есть такой список:

list = [{'item1': value1,
         'item2': [{'tinyitem21': tinyvalue21, 'tinyitem22': tinyvalue22}]},
        {'item3': [{'tinyitem31': tinyvalue31, 'tinyitem32': tinyvalue32}],
         'item4': value4}]

Я хочу получить такой список:

list = [{'item1': value1,
         'item2': {'tinyitem21': tinyvalue21, 'tinyitem22': tinyvalue22}},
        {'item3': {'tinyitem31': tinyvalue31, 'tinyitem32': tinyvalue32},
         'item4': value4}]

Я написал код ниже, чтобы попытаться решить эту проблему, но это не работает:

for item in list:
    for smallitem, smallvalue in item:
        if type(smallvalue)=='list':
            new_dict= {}
            for tinyitem in smallvalue:
                name = tinyitem.pop('name')
                new_dict[name] = tinyitem
            smallvalue=new_dict

Кто-нибудь может мне помочь?

Ответы [ 3 ]

5 голосов
/ 07 февраля 2020

Вы можете использовать эту функцию (обратите внимание, что список изменяется на месте):

Код:

def f(l):
    for d in l:
        for k, v in d.items():
            if isinstance(v, list):
                d[k] = v[0]
    return l

Вывод:

>>> f(lst)
[{'item1': value1,
  'item2': {'tinyitem21': tinyvalue21, 'tinyitem22': tinyvalue22}},
 {'item3': {'tinyitem31': tinyvalue31, 'tinyitem32': tinyvalue32},
  'item4': value4}]

Вы также можете использовать понимание списков / диктов:

>>> [{k: v[0] if isinstance(v, list) else v for k, v in d.items()} for d in lst]
[{'item1': value1,
  'item2': {'tinyitem21': tinyvalue21, 'tinyitem22': tinyvalue22}},
 {'item3': {'tinyitem31': tinyvalue31, 'tinyitem32': tinyvalue32},
  'item4': value4}]

Если у вас больше вложенных списков / диктов, чем один уровень, вы можете используйте эту рекурсивную функцию:

def f(lst):
    return [recursive_function(d) for d in lst] 

def recursive_function(d):
    rv = {}
    for k, v in d.items():
        if isinstance(v, list):
            v = v[0]
            if isinstance(v, dict):
                v = recursive_function(v)
        rv[k] = v
    return rv

Использование:

>>> lst = [{'item1': value1,
            'item2': [{'tinyitem21': [{'tinyitem21': tinyvalue21,
                                       'tinyitem22': tinyvalue22}],
                       'tinyitem22': tinyvalue22}]},
           {'item3': [{'tinyitem31': tinyvalue31, 'tinyitem32': tinyvalue32}],
            'item4': value4}]
>>> f(lst)
[{'item1': 'value1',
  'item2': {'tinyitem21': {'tinyitem21': tinyvalue21,
                           'tinyitem22': tinyvalue22},
            'tinyitem22': tinyvalue22}},
 {'item3': {'tinyitem31': tinyvalue31, 'tinyitem32': tinyvalue32},
  'item4': value'}]
1 голос
/ 07 февраля 2020

Вот решение для вложенного преобразования первого уровня.

import json

input_list = [{'item1':"value",'item2':[{'tinyitem21':'tinyvalue21','tinyitem22':'tinyvalue22'}]},{'item3':[{'tinyitem31':'tinyvalue31','tinyitem32':'tinyvalue32'}],'item4':'value4'}]

for index, j in enumerate(range(len(input_list))):
    for key, value in input_list[index].items():
        if isinstance(value, list) and len(value) == 1:  # Checking for single dictionary as multiple values of dict cannot considered as json
            input_list[index][key] = value[0]

print(json.dumps(input_list, indent=3))

Вывод:

[
   {
      "item1": "value",
      "item2": {
         "tinyitem21": "tinyvalue21",
         "tinyitem22": "tinyvalue22"
      }
   },
   {
      "item3": {
         "tinyitem31": "tinyvalue31",
         "tinyitem32": "tinyvalue32"
      },
      "item4": "value4"
   }
]

И, скажем, если значение в item2 в индексе 0 имеет больше чем один dict , тогда это должно рассматриваться как строковое значение, как показано ниже: output

import json

input_list = [{'item1':"value",'item2':[{'tinyitem21':'tinyvalue21','tinyitem22':'tinyvalue22'},{'tinyitem23':'tinyvalue21','tinyitem24':'tinyvalue22'}]},{'item3':[{'tinyitem31':'tinyvalue31','tinyitem32':'tinyvalue32'}],'item4':'value4'}]


for index, j in enumerate(range(len(input_list))):
    for key, value in input_list[index].items():
        if isinstance(value, list):  # without checking len of list
            input_list[index][key] = ','.join(map(str, value))  # string value be assigned instead of dictionary

print(json.dumps(input_list, indent=3))

Вывод будет строкой, а не dict, но если вы заметите, что item3 является единственным диктатом списка, но все же

[
   {
      "item1": "value",
      "item2": "{'tinyitem21': 'tinyvalue21', 'tinyitem22': 'tinyvalue22'},{'tinyitem23': 'tinyvalue21', 'tinyitem24': 'tinyvalue22'}"
   },
   {
      "item3": "{'tinyitem31': 'tinyvalue31', 'tinyitem32': 'tinyvalue32'}",
      "item4": "value4"
   }
]

Обрабатывать оба списка одним / несколькими диктовками с большей читабельностью.

for index, j in enumerate(range(len(input_list))):
    for key, value in input_list[index].items():
        if isinstance(value, list) and len(value) == 1:  # Checking for single dictionary as multiple values of dict cannot considered as json
            input_list[index][key] = value[0]
        if isinstance(value, list) and len(value) > 1:  # for list of dict with more than one 
            input_list[index][key] = ','.join(map(str, value))  # string value be assigned instead of dictionary

, если вы хотите использовать всеобъемлющий способ , упомянутый по CDJB вам нужно добавить еще одно условие, потому что если в случае списка с размером больше 1 он автоматически игнорирует второй индекс.

[{k: v[0] if isinstance(v, list) and len(v) == 1 else v for k, v in d.items()} for d in input_list]

Вывод:

[
   {
      "item1": "value",
      "item2": "{'tinyitem21': 'tinyvalue21', 'tinyitem22': 'tinyvalue22'},{'tinyitem23': 'tinyvalue21', 'tinyitem24': 'tinyvalue22'}"
   },
   {
      "item3": {
         "tinyitem31": "tinyvalue31",
         "tinyitem32": "tinyvalue32"
      },
      "item4": "value4"
   }
]
0 голосов
/ 07 февраля 2020

Один вкладыш в Python:

lt = [{'item1':'value1', 'item2':[{'tinyitem21':'tinyvalue21','tinyitem22':'tinyvalue22'}]}, {'item3':[{'tinyitem31':'tinyvalue31','tinyitem32':'tinyvalue32'}], 'item4': 'value4'}]

li = [{i:(j[0] if isinstance(j, list) and len(j) > 0 else j) for i,j in m.items()} for m in lt]

print(li)

Выходы:

[{'item1': 'value1', 'item2': {'tinyitem21': 'tinyvalue21', 'tinyitem22': 'tinyvalue22'}}, {'item3': {'tinyitem31': 'tinyvalue31', 'tinyitem32': 'tinyvalue32'}, 'item4': 'value4'}]

См. this для "Как использовать if / else в понимании словаря ?».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...