根据Ansible中的键值合并两个字典列表
Merging two list of dictionaries according to a key value in Ansible
我有两个词典列表。我想根据特定的键合并它们。
这是列表 1:
"list1": [
{ "a": "b", "c": "d" },
{ "a": "e", "c": "f" }
]
这是列表 2:
"list2": [
{ "a": "e", "g": "h" },
{ "a": "b", "g": "i" }
]
所以合并后的最终词典列表应该如下所示。合并应该根据键“a”的值来完成:
"list3": [
{ "a": "b", "c": "d", "g": "i" },
{ "a": "e", "c": "f", "g": "h" }
]
对于循环、迭代等,官方文档似乎不够。我找不到完成此任务的方法。
简单的选择是reverse第二个列表combine zip列出
list3: "{{ list1|zip(list2|reverse)|map('combine')|list }}"
给予
list3:
- {a: b, c: d, g: i}
- {a: e, c: f, g: h}
下一个选项是迭代第一个列表。在循环 select 中,将第二个列表中的项目组合起来。下面的表达式给出相同的结果
- set_fact:
list3: "{{ list3|d([]) + [item|combine(_selection)] }}"
loop: "{{ list1 }}"
vars:
_selection: "{{ list2|selectattr('a', '==', item.a)|combine }}"
如果你想
,你可以使用json_query代替selectattr
vars:
_selection: "{{ list2|json_query(_query)|combine }}"
_query: '[?a==`{{ item.a }}`]'
如果可以安装合集community.general use the filter lists_mergeby。下面的表达式给出相同的结果
list3: "{{ list1|lists_mergeby(list2, 'a') }}"
如果您无法安装该集合,请自行创建一个自定义过滤器。例如
shell> cat filter_plugins/my_lists_mergeby.py
from collections import defaultdict
from operator import itemgetter
def my_lists_mergeby(l1, l2, index):
d = defaultdict(dict)
for l in (l1, l2):
for elem in l:
if index in elem.keys():
d[elem[index]].update(elem)
return sorted(d.values(), key=itemgetter(index))
class FilterModule(object):
def filters(self):
return {
'my_lists_mergeby': my_lists_mergeby,
}
我有两个词典列表。我想根据特定的键合并它们。
这是列表 1:
"list1": [
{ "a": "b", "c": "d" },
{ "a": "e", "c": "f" }
]
这是列表 2:
"list2": [
{ "a": "e", "g": "h" },
{ "a": "b", "g": "i" }
]
所以合并后的最终词典列表应该如下所示。合并应该根据键“a”的值来完成:
"list3": [
{ "a": "b", "c": "d", "g": "i" },
{ "a": "e", "c": "f", "g": "h" }
]
对于循环、迭代等,官方文档似乎不够。我找不到完成此任务的方法。
简单的选择是reverse第二个列表combine zip列出
list3: "{{ list1|zip(list2|reverse)|map('combine')|list }}"
给予
list3:
- {a: b, c: d, g: i}
- {a: e, c: f, g: h}
下一个选项是迭代第一个列表。在循环 select 中,将第二个列表中的项目组合起来。下面的表达式给出相同的结果
- set_fact:
list3: "{{ list3|d([]) + [item|combine(_selection)] }}"
loop: "{{ list1 }}"
vars:
_selection: "{{ list2|selectattr('a', '==', item.a)|combine }}"
如果你想
,你可以使用json_query代替selectattr vars:
_selection: "{{ list2|json_query(_query)|combine }}"
_query: '[?a==`{{ item.a }}`]'
如果可以安装合集community.general use the filter lists_mergeby。下面的表达式给出相同的结果
list3: "{{ list1|lists_mergeby(list2, 'a') }}"
如果您无法安装该集合,请自行创建一个自定义过滤器。例如
shell> cat filter_plugins/my_lists_mergeby.py
from collections import defaultdict
from operator import itemgetter
def my_lists_mergeby(l1, l2, index):
d = defaultdict(dict)
for l in (l1, l2):
for elem in l:
if index in elem.keys():
d[elem[index]].update(elem)
return sorted(d.values(), key=itemgetter(index))
class FilterModule(object):
def filters(self):
return {
'my_lists_mergeby': my_lists_mergeby,
}