在字典中聚合值

2024-06-16 11:09:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一本很深的字典,像这样:

myDict = { '123456': {
              '348adbd39r' : {
                    'LONDON': {
                          'c_name': 'abc',
                          'acct': '84720'
                          },
                    'PARIS': {
                          'c_name': 'xyz',
                          'acct': '73642'
                          }
                     },

              '2862aef3' : {
                    'NYC': {
                          'c_name': 'hhdls3',
                          'acct': '92742'
                          }
                     },

              '82gfg24' : {
                    'NYC': {
                          'c_name': 'hquer',
                          'acct': '34567'
                          },
                    'PARIS': {
                          'c_name': 'ljad',
                          'acct': '93742'
                          }
                     }
        }

我想根据城市的名字来“聚合”它。输出应如下所示:

outDict = {
            'LONDON': {
                'c_name': ['abc'],
                'acct': ['84720']
             },
            'PARIS': {
                'c_name': ['xyz', 'ljad'],
                'acct': ['73642', '93742']
             },
            'NYC': {
                'c_name': ['hhdls3', 'hquer'],
                'acct': ['73642', '34567']
             }
         }

我就是这么做的:

cust_fields = ['c_name', 'acct']
field_dict = {field: [] for field in cust_fields}
aggregated_dict = {}

city_names = ['LONDON', 'PARIS', 'NYC']
for city in city_names:
   aggregated_dict[city] = field_dict


for id, an_dict in myDict.iteritems():
    for alphaNum, city_dict in an_dict.iteritems():
        for city, acct_dict in city_dict.iteritems():
            for field, val in acct_dict.iteritems():
                aggregated_dict[city][field].append(val)

但是,上面所说的是更新所有城市的字段值…而不仅仅是它正在处理的特定城市。不知道逻辑哪里错了。任何帮助(无论是纠正我的错误或任何新的逻辑…)。你知道吗

谢谢!你知道吗


Tags: nameincityfieldfordictmydictabc
3条回答

可以使用递归:

from collections import defaultdict
d1 = defaultdict(dict)
def aggregate(d):
   for a, b in d.items():
      if a in ['LONDON', 'PARIS', 'NYC']:
         global d1
         if a not in d1:

             d1[a] = {}

             d1[a]['c_name'] = [b['c_name']]
             d1[a]['acct'] = [b['acct']]
          else:
             d1[a]['c_name'].append([b['c_name']])
             d1[a]['acct'].append(b['acct'])
        else:
           aggregate(b)

aggregate(myDict)
print(dict(d1))

输出:

{'PARIS': {'acct': ['73642', '93742'], 'c_name': ['xyz', ['ljad']]}, 'NYC': {'acct': ['92742', '34567'], 'c_name': ['hhdls3', ['hquer']]}, 'LONDON': {'acct': ['84720'], 'c_name': ['abc']}}

你的问题是你在给你的city_names循环中的field_dict赋值给aggregated_dict[city],这只是给每个城市分配相同的字典。当您更新任何引用(对于任何城市)时,所有引用都会更新。你知道吗

一个简单的解决办法就是改变

for city in city_names:
   aggregated_dict[city] = field_dict

收件人:

for city in city_names:
   aggregated_dict[city] = {field: [] for field in cust_fields}

对于这种类型的聚合,我还要看collections.defaultdict。你知道吗

from collections import defaultdict

collected = defaultdict(lambda: defaultdict(list))

for _, city_records in myDict['123456'].items():
    for city_name, records in city_records.items():
        for record_name, record_value in records.items():
            collected[city_name][record_name].append(record_value)


for city_name, records in collected.items():
    print city_name
    print dict(records)
for key,val in myDict.items():
    for key1,val1 in val.items():
        for key2,val2 in val1.items():
            d = final_dict[key2] if key2 in final_dict else defaultdict(list)
            for k,v in val2.items():
                d[k].append(v)
            final_dict[key2] = d

相关问题 更多 >