Допустим, вы хотите удалить из своего словаря (объекта) все элементы со значением пустой строки.
Вход:
foo: key1: used key2: "" key3: another_used
вывод:
foo: key1: used key3: another_used
Прежде чем заняться гадостями Jinja2, рассмотрим версию на Python. Взгляните на красоту!
new_dict = {key:value for key, value in some_dict.items() if value}
Решение для Jinja2 (Ansible)
Ansible 2.7+:
set_fact: new_dict: '{{ some_dict|dict2items|rejectattr("value", "equalto", "")|list|items2dict }}'
Объяснение:
- some_dict преобразуется в список из
{“key”:key, “value”:value}
элементов фильтромdict2items
. - rejectattr берет атрибут «значение» из каждого элемента этого списка.
- … И примените фильтр «equalto» с пустой строкой agrument («»)
- … И отклоняет (пропускает) все элементы, где
equalto
возвращаетtrue
. (Это означает, что нужно пропустить все элементы сvalue == “”
) list
filter преобразует результирующий генератор в правильный список (этого требуетitems2dict
фильтр)- И, наконец,
items2dict
возьмите немного разреженный список и преобразуйте его обратно в словарь, используя то же соглашение, что иdict2items
. - Здесь мы используем
set_fact
, потому что это единственный способ сделать это с одинаковым именем переменной слева и справа:
set_fact: my_dict: '{{ my_dict|dict2items|rejectattr("value", "equalto", "")|list|items2dict }}'
Хотя это решение, я ненавижу его всей душой. Почему люди придумывают такие уродливые мерзкие выражения?