В чем может быть проблема, с постановлением данным?

Всем привет, подскажите пожалуйста из-за чего может быть проблема? Я получил данные список словарей. Это avg_2 и avg_1, и теперь мне надо найти общие значение и добавить к общим Client. Так как у них одинаковые значение у description и Name. Она работает на половину. Половина правильно а другую половину сопоставляет не правильно.

Есть ли аналог данного кода или решить как-то по-другому ?

Пример входных данных(их более 20к поэтому ток часть могу показать):

    avg_1=[
       {
          "Name": "alex1",
          "Object": "",
          "Ip": "",
          "Status": "",
          "Mac": "",
          "Sn": "",
          
       },
       {
          "Name": "alex2",
          "Object": "",
          "Ip": "",
          "Status": "",
          "Mac": "",
          "Sn": "",
          
       },
       {
          "Name": "alex3",
          "Object": "",
          "Ip": "",
          "Status": "",
          "Mac": "",
          "Sn": "",
          
       }]
    avg_2=
    
    [
       {
          "Client": [
             "Max",
             "San"
          ],
          "description": "alex3"
       },
       {
          "Client": [
             "Aro"
          ],
          "description": "alex2"
       },
        {
          "Client": [
             "Loli"
          ],
          "description": "alex4"
       },
       {
          "Client": [
             "Frank"
          ],
          "description": "alex1"
       }]
   

        def workerss(Awes, names):
            workers_lists = []
            for miners in Awes:
                workers_lists.append(miners[names])
            return workers_lists
        
        def intersection_lists(list3, list4):
            return set(list3).intersection(list4)
        
        Awe_3_wk = workers(avg_1,'Name')
        Awe_4_wk = workers(avg_2,'description')
        
        common_workerss = intersection_lists(Awe_3_wk, Awe_4_wk)
        
        for miner_3 in avg_1:
            if miner_3["Name"] in common_workerss:
                for miner_4 in avg_2:
                    if miner_4['description'] in miner_3['Name']:
                        miner_3['Client'] = miner_4['Client']

 result = [
       {
          "Name": "alex1",
          "Object": "",
          "Ip": "",
          "Status": "",
          "Mac": "",
          "Sn": "",
          "Client": [
             "Frank"
          ],
          
       },
       {
          "Name": "alex2",
          "Object": "",
          "Ip": "",
          "Status": "",
          "Mac": "",
          "Sn": "",
          "Client": [
             "Aro"
          ]
          
       },
       {
          "Name": "alex3",
          "Object": "",
          "Ip": "",
          "Status": "",
          "Mac": "",
          "Sn": "",
          "Client": [
             "Max",
             "San"
          ]
          }]


Во время дэбага отрабатывает все как надо :(

Ответы (3 шт):

Автор решения: n1tr0xs

Всё это можно сделать намного проще.

  1. Создаём вспомогательный словарь: desc_client = {d['description']: d['Client'] for d in avg_2}
  2. Бежим по списку avg_1, копируем словарь, чтобы исходные данные не поменялись. Добавляем пару из вспомогательного словаря.
res = []
for d in avg_1:
    new_d = dict(d)
    try:
        new_d['Client'].extend(desc_client[new_d['Name']])
    except KeyError:
        try:
            new_d['Client'] = desc_client[new_d['Name']]
        except KeyError:
            pass
    res.append(new_d)

Возможные сокращения кода при соблюдении условий входных данных:

  1. Если гарантируется, что не будет дублей description в avg_2 - try.. except заменяем на этот:
try:
    new_d['Client'] = desc_client[new_d['Name']]
except KeyError:
    pass
  1. Если гарантируется наличие каждого Name в avg_2 - try.. except нам не нужен, меняем на это:
new_d['Client'] = desc_client[new_d['Name']]

Возможное сокращение кода если список avg_1 можно менять и использовать как результат "вычислений-преобразований":

for d in avg_1:
    d['Client'] = desc_client[d['Name']] # тут вставить нужный вариант с try.. except
→ Ссылка
Автор решения: Namerek

На тему "по другому"

from dataclasses import dataclass, field, asdict

avg_1=[{"Name":"alex1","Object":"","Ip":"","Status":"","Mac":"","Sn":"",},{"Name":"alex2","Object":"","Ip":"","Status":"","Mac":"","Sn":"",},{"Name":"alex3","Object":"","Ip":"","Status":"","Mac":"","Sn":"",}]
avg_2=[{"Client":["Max","San"],"description":"alex3"},{"Client":["Aro"],"description":"alex2"},{"Client":["Crawl"],"description":"alex2"},{"Client":["Loli"],"description":"alex4"},{"Client":["Frank"],"description":"alex1"}]
@dataclass()
class Workers:
    Name: str
    Object: str
    Ip: str
    Status: str
    Mac: str
    Sn: str
    Clients: list = field(default_factory=lambda: [])

    def __eq__(self, other):
        return self.Name == other.description


@dataclass()
class ClientList:
    Client: list
    description: str

    def __eq__(self, other):
        if key := (self.description == other.Name):
            other.Clients += self.Client or []
        return key


c = [ClientList(**item) for item in avg_2]
w = [k for item in avg_1 if c.count(k := Workers(**item))]
print(
    *[asdict(
     item
    ) for item in w],
    sep='\n'
)
# {'Name': 'alex1', 'Object': '', 'Ip': '', 'Status': '', 'Mac': '', 'Sn': '', 'Clients': ['Frank']}
# {'Name': 'alex2', 'Object': '', 'Ip': '', 'Status': '', 'Mac': '', 'Sn': '', 'Clients': ['Aro', 'Crawl']}
# {'Name': 'alex3', 'Object': '', 'Ip': '', 'Status': '', 'Mac': '', 'Sn': '', 'Clients': ['Max', 'San']}
→ Ссылка
Автор решения: SergFSM

как альтернативный вариант можно попробовать pandas, на большом наборе данных его использование вполне оправдано:

import pandas as pd

df_1 = pd.DataFrame(avg_1)
df_2 = pd.DataFrame(avg_2).rename(columns={'description':'Name'})
res = df_1.merge(df_2,how='left').agg(dict,axis=1).tolist()

>>> res
'''
[{'Name': 'alex1',
  'Object': '',
  'Ip': '',
  'Status': '',
  'Mac': '',
  'Sn': '',
  'Client': ['Frank']},
 {'Name': 'alex2',
  'Object': '',
  'Ip': '',
  'Status': '',
  'Mac': '',
  'Sn': '',
  'Client': ['Aro']},
 {'Name': 'alex3',
  'Object': '',
  'Ip': '',
  'Status': '',
  'Mac': '',
  'Sn': '',
  'Client': ['Max', 'San']}]
→ Ссылка