2013-04-22 86 views
1

Jinja2中的sort filter有可能先后依次对一个列表进行排序,然后再由另一个属性进行排序?这似乎是一件很自然的事情,但在我的测试中,前面的排序完全不稳定,所有的排序都丢失了。Jinja2中的稳定排序

我已经在python中先排序,然后再将列表传递给模板,但我想知道是否可以在Jinja2中对“stable”进行排序。

我应用滤波器的方法是,像这样:

{{ item_list|sort(attribute='value')|sort(attribute='color') }} 

果然不出我所希望看到的是列表中color排序,共享由value排序的色彩元素。相反,它看起来好像从未发生过value

例如,从这个名单:

2 red 
3 blue 
3 red 
2 blue 
1 blue 
4 red 

我想是这样的:

1 blue 
2 blue 
3 blue 
2 red 
3 red 
4 red 

我看着groupby过滤器,但该实现似乎过于复杂(将嵌套的for循环需要)。

+0

的Jinja2将列表传递给第一排序函数和排序'value'。然后将返回的列表传递给第二个排序函数,并再次按'color'排序。很明显,这与仅仅通过'color'排序列表一样好,所以第一类被'覆盖' – RedBaron 2013-04-22 08:59:58

+0

@RedBaron我相信你错过了,在这个例子中,你可以拥有共享颜色的元素,但是有不同的价值。我将添加一个示例输出来澄清。 – ford 2013-04-22 09:05:41

回答

6

我不知道可以做到这一点的原生jinja2过滤器。要根据多个属性对列表进行排序,您可以在jinja2中定义一个custom filter

从接受的答案this question,您可以编写自己的过滤器

import operator 

def sort_multi(L,*operators): 
    L.sort(key=operator.itemgetter(*operators)) 
    return L 

注册在你的应用环境。因此,对于pyramid,你会做这样的事情

env = config.get_jinja2_environment() 
env.filters['sort_multi'] = sort_multi 

最后在模板

{{item_list|sort_multi('value','color')}} 
+0

这看起来像一个优雅的解决方案。我会尝试它(在Flask中)并接受它是否有效。谢谢! – ford 2013-04-22 22:24:23

+0

刚刚过了我的头顶。在sort()中传递一个元组到''attribute'是否工作? – RedBaron 2013-04-23 04:27:44

+0

仍然没有机会测试这个,但看看[排序方法](http://docs.python.org/2/howto/sorting.html),我认为不是。另外,我应该使用operator.attrgetter而不是itemgetter。 – ford 2013-04-23 17:06:58

相关问题