1

似乎您不能在不丢失排序顺序的情况下对 jinja 中的排序列表进行分组。

这是一个示例模板:

{% set l = [{'c': 3, 'result': 1.0},
            {'c': 3, 'result': 2.0},
            {'c': 9, 'result': 3.0},
            {'c': 1, 'result': 4.0}] %}
{% for d in l|groupby('c') %}
    {{d}}
{% endfor %}

不幸的是,这个模板输出:

(1, [{'c': 1, 'result': 4.0}])
(3, [{'c': 3, 'result': 1.0}, {'c': 3, 'result': 2.0}])
(9, [{'c': 9, 'result': 3.0}])

但我所期待的是:

(3, [{'c': 3, 'result': 1.0}, {'c': 3, 'result': 2.0}])
(9, [{'c': 9, 'result': 3.0}])
(1, [{'c': 1, 'result': 4.0}])

我必须绝对按照预先排序的顺序保存物品。

有谁知道如何实现这一目标?

4

3 回答 3

2

希望这个答案能解决你的问题

{% for d in l|groupby('c')|reverse %}
   {{d}}
{% endfor %}
于 2020-02-16T13:28:48.910 回答
1

更新到最新的 jinja 版本:

import jinja2

from jinja2 import environmentfilter
from itertools import groupby
from jinja2.filters import make_attrgetter, _GroupTuple

@environmentfilter
def do_sorted_groupby(environment, value, attribute):
    expr = make_attrgetter(environment, attribute)
    return [_GroupTuple(key, list(values)) for key, values
            in groupby(value, expr)]

env = jinja2.Environment()
env.filters['sorted_groupby'] = do_sorted_groupby

ret = env.from_string('''
{% set l = [{'c': 3, 'result': 1.0},
            {'c': 3, 'result': 2.0},
            {'c': 9, 'result': 3.0},
            {'c': 1, 'result': 4.0}] %}
{% for d in l|sorted_groupby('c') %}
    {{d}}
{% endfor %}
''').render()

print(ret)
于 2017-06-15T15:08:40.183 回答
0

正如@Blender 在他的评论中指出的那样,jinja 使用sorted根据收到的密钥对传递的列表进行排序。

如果您想保持排序顺序,我担心唯一的解决方案是编写自己的 jinja-filter。

这是我实现的过滤器:

from jinja2 import environmentfilter
from itertools import groupby
from jinja2.filters import make_attrgetter, _GroupTuple
@environmentfilter
def do_groupby(environment, value, attribute):
    expr = make_attrgetter(environment, attribute)
    return map(_GroupTuple, groupby(value, expr))

注意:此过滤器仅在接收到的列表正确分组时才起作用(组指示符必须按顺序排列)。例如,此列表将无法正确分组:

[{'c': 3, 'result': 1.0},
 {'c': 9, 'result': 2.0},
 {'c': 3, 'result': 3.0},
 {'c': 1, 'result': 4.0}]
于 2013-07-13T06:13:35.287 回答