按元组第二个值降序和第一个值升序排序列表
我需要对一个字典进行排序,首先是根据值进行排序,使用 reverse=True
,也就是说要把值大的排在前面;如果有重复的值,就要根据键进行排序,这时使用 reverse=False
,也就是把键小的排在前面。
到目前为止,我有这个:
dict = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
sorted(dict.items(), key=lambda x: (x[1],x[1]), reverse=True)
这个返回了...
[('B', 3), ('A', 2), ('J', 1), ('I', 1), ('A', 1)]
但我需要的是:
[('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
如你所见,当值相等时,我只能按照指定的方式让键降序排列...但是我该如何让它们按升序排列呢?
3 个回答
你可以使用 collections.defaultdict
:
In [48]: from collections import defaultdict
In [49]: dic=[('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
In [50]: d=defaultdict(list)
In [51]: for x,y in dic:
d[y].append(x)
d[y].sort() #sort the list
现在 d
看起来像这样:
defaultdict(<type 'list'>, {1: ['A', 'I', 'J'], 2: ['A'], 3: ['B']}
也就是说,这是一个新的 dict
,它的键是 1,2,3...
,对应的值是存储在列表中的字母。
现在你可以通过 sorted(d.items)
来遍历这个字典,并使用 itertools.chain()
和 itertools.product()
来得到你想要的结果。
In [65]: l=[ product(y,[x]) for x,y in sorted(d.items(),reverse=True)]
In [66]: list(chain(*l))
Out[66]: [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
在编程中,有时候我们会遇到一些问题,可能是因为代码写得不够清晰,或者是我们对某个概念理解得不够透彻。比如说,有人可能在使用某个函数时,不太明白它的作用或者用法。这种情况下,查看相关的讨论或者提问是很有帮助的。
在StackOverflow上,很多人会分享他们的经验和解决方案。你可以看到不同的观点和方法,这样可以帮助你更好地理解问题所在。记得多看看别人的代码和解释,慢慢你就会掌握这些知识。
总之,遇到问题不要怕,积极寻求帮助和学习,编程的路上总会有新的发现和成长。
In [4]: l = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
In [5]: sorted(l, key=lambda (x,y):(-y,x))
Out[5]: [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
下面的代码可以处理你的输入:
d = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
sorted(d,key=lambda x:(-x[1],x[0]))
因为你的“值”是数字,所以你可以通过改变符号来轻松反转排序顺序。
换句话说,这种排序方式是先根据值来排序(-x[1]
),负号的作用是把大的数字排在前面;如果有数字相同的情况,就根据键(x[0]
)来排序。
如果你的值不能简单地通过“取反”来让大的项目排在前面,还有一个简单的解决办法就是排序两次:
from operator import itemgetter
d.sort(key=itemgetter(0))
d.sort(key=itemgetter(1),reverse=True)
这样做是有效的,因为Python的排序是稳定的。