Jinja按条件筛选列表输出、仅省略最后一项末尾逗号的实现问题
问题原因
你原来的代码中loop.last判断的是原始遍历列表的最后一项,而非筛选后输出内容的最后一项。如果原始列表的最后一项不符合states(entity_id) == 'on'的筛选条件,筛选结果的最后一项永远不会触发loop.last分支,就会出现末尾多逗号的问题。
解决方法
推荐两种成熟的实现方案:
方案1:先筛选再遍历(逻辑直观)
先把符合条件的实体名称预处理成独立列表,再遍历这个列表拼接内容,此时loop.last对应的就是筛选后列表的最后一项,判断逻辑完全准确:
{%- set updater_names = [] -%} {%- for entity_id in states.group.all_updater_entities.attributes.entity_id -%} {%- if states(entity_id) == 'on' -%} {%- set _ = updater_names.append(state_attr(entity_id, 'friendly_name') | replace('Updater', '')) -%} {%- endif -%} {%- endfor -%} {%- for name in updater_names -%} {{ name }}{% if not loop.last %}, {% endif %} {%- endfor -%} has updates available.
方案2:用Jinja内置join过滤器(代码最简)
Jinja自带的join过滤器本身就支持自动在列表元素间插入分隔符,不会在末尾多余添加,完全不需要手动判断循环位置:
{%- set updater_names = [] -%} {%- for entity_id in states.group.all_updater_entities.attributes.entity_id -%} {%- if states(entity_id) == 'on' -%} {%- set _ = updater_names.append(state_attr(entity_id, 'friendly_name') | replace('Updater', '')) -%} {%- endif -%} {%- endfor -%} {{ updater_names | join(', ') }} has updates available.
额外优化提示:如果需要处理没有待更新实体的场景,避免输出无主语的
has updates available.,可以在外层加非空判断:{% if updater_names | length > 0 %} {{ updater_names | join(', ') }} has updates available. {% endif %}
内容的提问来源于stack exchange,提问作者Abhi O.
相关产品推荐
相关产品推荐

