Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 29, 2018 12:39:36

Vort
Зарегистрирован: 2014-01-09
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Объединение двух вложенных словарей по условию.

Буду очень благодарен за совет, как решить такое:
Есть list из dict-ов, типа:

 entities_list = [
    {
        "period": 190,
        "entity_name": "metadata",
        "operation": "delete",
        "fields": "age"
    },
    {
        "period": 120,
        "entity_name": "metadata",
        "operation": "hash",
        "fields": "customer_id"
    },
    {
        "period": 30,
        "entity_name": "qtnn-details",
        "operation": "hash",
        "fields": "*"
    },
    {
        "period": 90,
        "entity_name": "address",
        "operation": "hash",
        "fields": "*"
    },
    {
        "period": 120,
        "entity_name": "metadata",
        "operation": "hash",
        "fields": "first_name"
    },
    {
        "period": 30,
        "entity_name": "qtnn-details",
        "operation": "delete",
        "fields": "invite_survey"
    },
    {
        "period": 30,
        "entity_name": "qtnn-details",
        "operation": "delete",
        "fields": "msisdn"
    }
]

Его надо перебрать и при совпадении “entity_name” и “operation”, строкове значение поля “fields”, превратить в {'first_name': 120} (если fields был first_name, а period 120).
Чтобы получились dict-ы, сгруппированные таким образом
 {
    "entity_name": "metadata",
    "period": 120,
    "operation": "hash",
    "fields": {
      "first_name": 120,
      "customer_id": 120
    }
  }

Пытаюсь делать так:
     merged = []
    for entity in entities_list:
        if merged:
            for item in merged:
                if (
                        item['entity_name'] == entity['entity_name'] and
                        item['operation'] == entity['operation']
                ):
                    if isinstance(item['fields'], str) and item['fields'] != '*':
                        item['fields'] = {
                            item['fields']: item['period'],
                            entity['fields']: entity['period']
                        }
                    elif isinstance(item['fields'], dict):
                        item['fields'].update({
                            entity['fields']: entity['period']
                        })
                    continue
                else:
                    if entity not in merged:
                        merged.append(entity)
                    continue
        else:
            merged.append(entity)

Но в итоге цикл, начинаает ходить повторно, по второму листу. Посоветуйте пожалуйста, как такое лучше решить?

Отредактировано Vort (Сен. 29, 2018 12:41:46)

Офлайн

#2 Сен. 29, 2018 15:43:52

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Объединение двух вложенных словарей по условию.

А что мешает вам делать так как вы написали?

 for d in entities_list:
   if d["entity_name"]== d["operation"]:
       d["fields"] = {d["firstname"]:d["period"]}
Vort
сгруппированные таким образом
непонятно к чему относится.

Если надо что-то группировать это не проблема тоже:
 from collections import dafaultdict
merged = defaultdict(list)
for d in entities_list:
  merged[(d["entity_name"],d["operation"])].append(d)
....



Офлайн

#3 Сен. 29, 2018 19:28:53

Vort
Зарегистрирован: 2014-01-09
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Объединение двух вложенных словарей по условию.

doza_and
непонятно к чему относится.
Я может неточно выразился, дело в том, что записи могут повторяться и имена вложенного fields заранее неизвестны. И словари типа
     {
        "period": 120,
        "entity_name": "metadata",
        "operation": "hash",
        "fields": "customer_id"
    },
    {
        "period": 120,
        "entity_name": "metadata",
        "operation": "hash",
        "fields": "first_name"
    }
надо на выходе сливать в один:
 {
        "period": 120,
        "entity_name": "metadata",
        "operation": "hash",
        "fields": {
            "first_name": 120,
            "customer_id": 120
        }
   }

Отредактировано Vort (Сен. 29, 2018 19:29:28)

Офлайн

#4 Сен. 30, 2018 06:25:06

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10022
Репутация: +  857  -
Профиль   Отправить e-mail  

Объединение двух вложенных словарей по условию.

Надо сначала выбрать словари для слияния, а уже потом выбранные словари сливать. Не надо всё делать одновременно.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version