似乎你不能在不丢失排序顺序的情况下对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}])
我绝对要按照预先排序的顺序保留这些项目。
有人知道如何实现这个目标吗?
答案 0 :(得分: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)
答案 1 :(得分:0)
正如@Blender在评论中指出的那样,jinja使用sorted
根据收到的密钥对传递的列表进行排序。
如果您想保留排序顺序,我担心唯一的解决方案是编写自己的jinja过滤器。
这里实现了我实现的过滤器:
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}]
答案 2 :(得分:0)
希望这个答案能解决您的问题
{% for d in l|groupby('c')|reverse %}
{{d}}
{% endfor %}