Jinja2中列表的唯一过滤器

jon*_*han 3 jinja2 python-3.x

我有以下 YAML 结构:

bri:
  cards:
    - slot: "1"
      subslot: "0"
      ports: 2
    - slot: "1"
      subslot: "1"
      ports: 2
    - slot: "1"
      subslot: "2"
      ports: 2
    - slot: "2"
      subslot: "0"
      ports: 2
    - slot: "2"
      subslot: "1"
      ports: 2
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用 Jinja2 来获取唯一的slot列表,即:

['1', '2']
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经成功地应用了以下内容:

{{ bri.cards|map(attribute='slot')|list }}
Run Code Online (Sandbox Code Playgroud)

这给了我:

['1', '1', '1', '2', '2']
Run Code Online (Sandbox Code Playgroud)

但是,我似乎无法找到获得唯一列表的方法。

Ansible

Ansible 似乎有一个“独特”的过滤器可以做到这一点。但在这种情况下我没有使用 Ansible。

我的问题

任何人都可以建议实现这一目标的最佳方法吗?应该(或可以)使用 Jinja2 本地完成,还是应该采用替代方法?

dor*_*oru 6

你可以做这样的事情(取决于你如何解析.yaml文件——它是一个dicts的dicts列表吗?):

{% set slots = [] %}
{% for slot in bri.cards if slot not in slots %}
    {% do slots.append(slot) %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)


Edg*_*gón 6

自从jinja2 2.10

unique在 version 中添加了一个过滤器2.10。您可以查看更改日志PR

使用示例

from jinja2 import Template


template = Template("""
  {% for x in a|unique %}
    <li>{{ x }}</li>
  {% endfor %}
""")

r = template.render(a=[1, 2, 3, 4, 1, 5, 4])

print(r)
Run Code Online (Sandbox Code Playgroud)

输出:

<li>1</li>

<li>2</li>

<li>3</li>

<li>4</li>

<li>5</li>
Run Code Online (Sandbox Code Playgroud)


Mz *_*z A 5

已编辑- 我没有看到有关无法使用独特过滤器的内容。对于那些可以使用独特过滤器的人,你可以这样做

{{ bri.cards|map(attribute='slot')|unique|list }}
Run Code Online (Sandbox Code Playgroud)