我有一系列这样的口述记录:
list_of_dicts:
- name: Item1
- name: Item2
type: special
- name: Item3
- name: Item4
type: small
如您所见,并非所有项目都有type
属性。上下文:如果没有type
设置属性,则表示该项目属于默认类型。
我想选择所有不属于类型的项目special
。
我尝试过这个:list_of_dicts | rejectattr('type', 'equalto', 'special')
AnsibleUndefinedVariable: 'dict object' has no attribute 'type'
不幸的是,由于某些项目没有类型,因此此操作失败并出现错误。
有什么好方法可以解决这个问题?
答案1
编辑:我实际上没有足够关注@ranjandas 对现有答案的最新编辑以及以下评论。我的第一个解决方案几乎相似。我猜你对第二个更感兴趣。
这里有两种不同的方法可以满足您的要求。
第一个解决方案仅使用 ansible 中默认可用的过滤器:
rejectattr
您已经提到的 和它的对应项selectattr
。这个想法是添加两个列表。第一个是通过选择所有没有type
属性的字典来制作的。第二个是通过选择具有type
属性的字典并拒绝那些等于 的字典来制作的special
。对于第二个解决方案,我使用了
json_query
筛选这需要pip install jmespath
控制器。正如您在下面看到的,它更加紧凑。
这是你的选择 !
演示剧本:
---
- name: Show not so special items
hosts: localhost
gather_facts: false
vars:
list_of_dicts:
- name: Item1
- name: Item2
type: special
- name: Item3
- name: Item4
type: small
tasks:
- name: Use select/rejectattr
debug:
msg: >-
{{
(list_of_dicts | selectattr('type', 'undefined') | list)
+
(list_of_dicts | selectattr('type', 'defined') | rejectattr('type', 'eq', 'special') | list)
}}
- name: Use json_query
vars:
query: "[?type != 'special']"
debug:
msg: "{{ list_of_dicts | json_query(query) | list }}"
这使:
PLAY [Show not so special items] **********************************************************************************************************************************************************************************
TASK [Use select/rejectattr] **************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
{
"name": "Item1"
},
{
"name": "Item3"
},
{
"name": "Item4",
"type": "small"
}
]
}
TASK [Use json_query] *********************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
{
"name": "Item1"
},
{
"name": "Item3"
},
{
"name": "Item4",
"type": "small"
}
]
}
PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
答案2
您应该使用rejectattr
来拒绝type
未定义的项目并使用selectattr
选择特殊的项目equalto
。
{{ list_of_dicts | rejectattr("type", "undefined") | selectattr("type", "equalto", "special") | list }}
编辑:
如何将下面给出的两个列表合并起来?我不知道这是否是最好的方法,但它确实有效。
{{ list_of_dicts | selectattr("type", "undefined") | list }} + {{ list_of_dicts | rejectattr("type", "undefined") | rejectattr("type", "equalto", "special") | list}}