我有一个k元素的元组列表。我想对元素0进行排序,然后对元素1进行排序,依此类推。我用谷歌搜索,但我仍然无法弄清楚如何做到这一点。它会是这样的吗?
list.sort(key = lambda x : (x[0], x[1], ...., x[k-1])
特别是,我想使用不同的标准排序,例如,降序元素0,升序元素1,依此类推。
答案 0 :(得分:1)
list.sort(key = lambda x : (x[0], x[1], ...., x[k-1])
这实际上是使用元组作为自己的排序键。换句话说,就像调用sort()
而没有参数一样。
如果我假设您简化了问题,并且实际元素实际上与您要排序的顺序不同(例如,最后一个值具有最高优先级),则可以使用相同的技术,但重新排序基于优先级的密钥部分:
list.sort(key = lambda x : (x[k-1], x[1], ...., x[0])
一般来说,这是一个非常方便的技巧,即使在其他语言如C ++中(如果您正在使用库):当您想要由具有不同优先级的多个成员对对象列表进行排序时,您可以构建一个通过按优先顺序制作包含所有相关成员的元组来排序键。
最后一招(这个是主题,但它可能在某些时候对你有所帮助):当使用一个不支持"排序的图书馆时,#34;通过构建包含排序键的列表,您通常可以获得相同的效果。因此,不是排序Obj
列表,而是构造然后对元组列表进行排序:(ObjSortKey, Obj)
。此外,如果排序键是唯一的,只需将对象插入到有序集中即可。 (在这种情况下,排序键将是索引。)
答案 1 :(得分:1)
自python's sort
is stable for versions after 2.2(或perhaps 2.3)以来,我能想到的最简单的实现是使用一系列sort
元组连续重复index, reverse_value
:
# Specify the index, and whether reverse should be True/False
sort_spec = ((0, True), (1, False), (2, False), (3, True))
# Sort repeatedly from last tuple to the first, to have final output be
# sorted by first tuple, and ties sorted by second tuple etc
for index, reverse_value in sort_spec[::-1]:
list_of_tuples.sort(key = lambda x: x[index], reverse=reverse_value)
这会进行多次传递,因此就恒定时间成本而言可能效率低,但在渐近复杂度方面仍然是O(nlogn)。
如果索引的排序顺序对于n个大小的元组列表是真正的0, 1... n-1, n
,如示例所示,那么您只需要一个True和False序列来表示是否需要{{1}或不,您可以使用reverse
添加索引。
enumerate
虽然原始代码允许按任何索引顺序进行排序的灵活性。
顺便提一下,这个“排序顺序”方法建议在Python Sorting HOWTO中稍作修改。
修改强> 如果您没有要求按某些索引对升序进行排序并按其他索引递减,那么
sort_spec = (True, False, False, True)
for index, reverse_value in list(enumerate(sort_spec))[::-1]:
list_of_tuples.sort(key = lambda x: x[index], reverse=reverse_value)
将按索引1排序,然后关系将按索引3排序,并进一步按索引5排序。但是,更改每个索引的升序/降序在一遍中是非平凡的。
答案 2 :(得分:0)
所以我假设您想要将tuple_0升序排序,然后将tuple_1降序排序,依此类推。有点冗长但这可能是你想要的:
ctr = 0
for i in range(list_of_tuples):
if ctr%2 == 0:
list_of_tuples[0] = sorted(list_of_tuples[0])
else:
list_of_tuples[0] = sorted(list_of_tuples[0], reverse=True)
ctr+=1
print list_of_tuples