【问题标题】:Is there an elegant way to merge to merge a list of dicts by a common key?有没有一种优雅的方法来合并以通过公共键合并字典列表?
【发布时间】:2021-04-24 15:07:53
【问题描述】:

我正在寻找一种更优雅的方法来将此字典列表转换为单个合并字典,其中键“sku”作为合并键。该列表实际上是 Pydantic 模型,很容易变成字典。我没有找到使用 Pydantic 的更优雅的解决方案。

dicts/pydanticinstances 列表

[a for a in m]
[
    PackMapPydantic(id=60, pack_sku='PACKFAC01', sku='FAC01', prop_name='Facebook Username'),
    PackMapPydantic(id=61, pack_sku='PACKFAC01', sku='FAC02', prop_name='Facebook Username'),
    PackMapPydantic(id=62, pack_sku='PACKFAC01', sku='FAC03', prop_name='Facebook Username'),
    PackMapPydantic(id=63, pack_sku='PACKFAC01', sku='FAC05', prop_name='Facebook Username'),
    PackMapPydantic(id=64, pack_sku='PACKFAC01', sku='FAC06', prop_name='Facebook Username'),
    PackMapPydantic(id=70, pack_sku='PACKFAC01', sku='FAC01', prop_name='Channel Name'),
    PackMapPydantic(id=71, pack_sku='PACKFAC01', sku='FAC02', prop_name='Channel Name'),
    PackMapPydantic(id=72, pack_sku='PACKFAC01', sku='FAC03', prop_name='Channel Name'),
    PackMapPydantic(id=73, pack_sku='PACKFAC01', sku='FAC05', prop_name='Channel Name'),
    PackMapPydantic(id=74, pack_sku='PACKFAC01', sku='FAC06', prop_name='Channel Name'),
    PackMapPydantic(id=87, pack_sku='PACKFAC01', sku='FAC01', prop_name='__uk_avatar (direct link)'),
    PackMapPydantic(id=88, pack_sku='PACKFAC01', sku='FAC02', prop_name='__uk_avatar (direct link)'),
    PackMapPydantic(id=89, pack_sku='PACKFAC01', sku='FAC03', prop_name='__uk_avatar (direct link)'),
    PackMapPydantic(id=90, pack_sku='PACKFAC01', sku='FAC06', prop_name='__uk_avatar (direct link)')
]

期望的输出:

[
  {
      'sku': 'FAC05', 
      'prop_name': [
          'Username', 
          'Channel'
      ]
  },
  {
      'sku': 'FAC01',
      'prop_name': [
          'Username',
          'Channel',
          '__uk_avatar (direct link)'
      ]
  },
  {
      'sku': 'FAC06',
      'prop_name': [
          'Username',
          'Channel',
          '__uk_avatar (direct link)'
      ]
  },
  {
      'sku': 'FAC02',
      'prop_name': [
          'Username',
          '__uk_avatar (direct link)'
      ]
  },
  {
      'sku': 'FAC03',
      'prop_name': [
          'Username',
          'Channel',
          '__uk_avatar (direct link)'
      ]
  }
]

目前的解决方案:

for sku in skus_distinct:
    this_assets = []
    for item in items_listed:
        if item['sku'] == sku:
            # item = list(item)
            this_assets.append(item['prop_name'])

    now = {'sku': sku,
           'prop_name': this_assets }

    print(now)

【问题讨论】:

  • 您可以在code review platform 上发布此问题,因为您想找到改进代码的方法。请查看此link 以了解这些平台之间的区别。

标签: python data-structures pydantic


【解决方案1】:

你可以使用collections.defaultdict:

from collections import defaultdict
d = defaultdict(list)
for i in data:
  d[i.sku].append(i.prop_name)

result = [{'sku':a, 'prop_name':b} for a, b in d.items()]

输出:

[{'sku': 'FAC01', 'prop_name': ['Facebook Username', 'Channel Name', '__uk_avatar (direct link)']}, {'sku': 'FAC02', 'prop_name': ['Facebook Username', 'Channel Name', '__uk_avatar (direct link)']}, {'sku': 'FAC03', 'prop_name': ['Facebook Username', 'Channel Name', '__uk_avatar (direct link)']}, {'sku': 'FAC05', 'prop_name': ['Facebook Username', 'Channel Name']}, {'sku': 'FAC06', 'prop_name': ['Facebook Username', 'Channel Name', '__uk_avatar (direct link)']}]

【讨论】:

    【解决方案2】:

    使用 pandas(假设 dict1 是您的初始 dict 列表)-

    import pandas as pd
    df  = pd.DataFrame(dict1)[['sku','prop_name']]
    df  = df.groupby('sku').agg({'prop_name': list}).reset_index()
    result_dict = df.to_dict(orient='records')
    

    输出 -

    [{'sku': 'FAC01',
      'prop_name': ['Facebook Username',
       'Channel Name',
       '__uk_avatar {direct link}']},
     {'sku': 'FAC02',
      'prop_name': ['Facebook Username',
       'Channel Name',
       '__uk_avatar {direct link}']},
     {'sku': 'FAC03',
      'prop_name': ['Facebook Username',
       'Channel Name',
       '__uk_avatar {direct link}']},
     {'sku': 'FAC05', 'prop_name': ['Facebook Username', 'Channel Name']},
     {'sku': 'FAC06',
      'prop_name': ['Facebook Username',
       'Channel Name',
       '__uk_avatar {direct link}']}]
    

    【讨论】:

      猜你喜欢
      • 2017-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 2020-02-14
      • 1970-01-01
      • 2011-12-22
      相关资源
      最近更新 更多