通过匹配python中的内部dicts属性来展平两个dicts列表?

时间:2017-12-14 20:54:38

标签: python python-2.7 dictionary

背景 我从后端(regions =[])获取了一些数据,我需要通过匹配slug为列表中的每个dict添加一个属性(order = [])。我将在jinja模板过滤器中按此属性排序。

在javascript中我会使用像mapzip等功能数组方法;不幸的是,我是一个python noob,我不知道这些方法的等价物是什么。

问题:

如何将列表order简洁地展平为regions并在python中收到预期的输出regions_with_order

Repl

# I made this to zip into regions
order = [
  {'slug': 'north-america', 'order': 1},
  {'slug': 'latin-america', 'order': 2},
  {'slug': 'europe', 'order': 3},
  {'slug': 'asia-pacific', 'order': 4},
  {'slug': 'africa-middle-east', 'order': 5},
]

# I received this from backend cms.   
regions = [
  {'slug': 'africa-middle-east', 'lat': '123'},     
  {'slug': 'europe','lat': '1231'},
  {'slug': 'asia-pacific', 'lat': '1230'},
  {'slug': 'latin-america',  'lat': '1232'},
  {'slug': 'north-america', 'lat': '1234'},
]



# Expected OUTPUT

# regions_with_order = [
#   {'slug': 'north-america', 'lat': '1234',  'order': 1},
#   {'slug': 'latin-america',  'lat': '1232',  'order': 2},
#   {'slug': 'europe','lat': '1231', 'order': 3},
#   {'slug': 'asia-pacific', 'lat': '1230','order': 4},
#   {'slug': 'africa-middle-east', 'lat': '123','order': 5}
# ]

2 个答案:

答案 0 :(得分:3)

首先将区域列表转换为字典,这样您就可以通过slug查找每个区域的lat值,高效

def merge_dicts(d1, *ds):
    final = d1.copy()
    for d in ds:
        final.update(d)
    return final

regionmap = {r['slug']: r for r in regions}
regions_with_order = [merge_dicts(o, regionmap[o['slug']]) for o in order]

在Python 3中,您可以将merge_dicts()来电替换为{**o, **regionmap[o['slug']]}

这会产生您想要的输出:

>>> from pprint import pprint
>>> order = [
...   {'slug': 'north-america', 'order': 1},
...   {'slug': 'latin-america', 'order': 2},
...   {'slug': 'europe', 'order': 3},
...   {'slug': 'asia-pacific', 'order': 4},
...   {'slug': 'africa-middle-east', 'order': 5},
... ]
>>> regions = [
...   {'slug': 'africa-middle-east', 'lat': '123'},
...   {'slug': 'europe','lat': '1231'},
...   {'slug': 'asia-pacific', 'lat': '1230'},
...   {'slug': 'latin-america',  'lat': '1232'},
...   {'slug': 'north-america', 'lat': '1234'},
... ]
>>> regionmap = {r['slug']: r['lat'] for r in regions}
>>> [merge_dicts(o, regionmap[o['slug']]) for o in order]
[{'slug': 'north-america', 'order': 1, 'lat': '1234'}, {'slug': 'latin-america', 'order': 2, 'lat': '1232'}, {'slug': 'europe', 'order': 3, 'lat': '1231'}, {'slug': 'asia-pacific', 'order': 4, 'lat': '1230'}, {'slug': 'africa-middle-east', 'order': 5, 'lat': '123'}]
>>> pprint(_)
[{'lat': '1234', 'order': 1, 'slug': 'north-america'},
 {'lat': '1232', 'order': 2, 'slug': 'latin-america'},
 {'lat': '1231', 'order': 3, 'slug': 'europe'},
 {'lat': '1230', 'order': 4, 'slug': 'asia-pacific'},
 {'lat': '123', 'order': 5, 'slug': 'africa-middle-east'}]

答案 1 :(得分:0)

你可以试试这个:

order = [
  {'slug': 'north-america', 'order': 1},
  {'slug': 'latin-america', 'order': 2},
  {'slug': 'europe', 'order': 3},
  {'slug': 'asia-pacific', 'order': 4},
  {'slug': 'africa-middle-east', 'order': 5}
]

regions = [
  {'slug': 'africa-middle-east', 'lat': '123'},

  {'slug': 'europe','lat': '1231'},
  {'slug': 'asia-pacific', 'lat': '1230'},
  {'slug': 'latin-america',  'lat': '1232'},
  {'slug': 'north-america', 'lat': '1234'},
]
final_data = [{'slug':i['slug'], 'lat':i['lat'], 'order':[c['order'] for c in order if c['slug'] == i['slug']][0]} for i in regions]

输出:

[{'lat': '123', 'slug': 'africa-middle-east', 'order': 5}, 
{'lat': '1231', 'slug': 'europe', 'order': 3}, 
{'lat': '1230', 'slug': 'asia-pacific', 'order': 4}, 
{'lat': '1232', 'slug': 'latin-america', 'order': 2}, 
{'lat': '1234', 'slug': 'north-america', 'order': 1}]

如果区域具有任意长度,您可以在Python3中尝试:

new_list = sorted([{**i, **{'order':[c['order'] for c in order if c['slug'] == i['slug']][0]}} for i in regions], key=lambda x:x['order'])

输出:

[{'slug': 'north-america', 'lat': '1234', 'order': 1}, 
{'slug': 'latin-america', 'lat': '1232', 'order': 2}, 
{'slug': 'europe', 'lat': '1231', 'order': 3}, 
{'slug': 'asia-pacific', 'lat': '1230', 'order': 4}, 
{'slug': 'africa-middle-east', 'lat': '123', 'order': 5}]