Python:按项频率排序元组列表
假设我有一个列表:
tmp = [((0,0), (1,1)), ((1,2), (3,4)), ((1,2), (5,6))]
我想把它排序,排序的标准是根据每对元素出现的频率来决定,所谓“出现频率最高的对”是指每对中第一个元素的出现次数:
>>> [((1, 2), (3, 4)), ((1, 2), (5, 6)), ((0, 0), (1, 1))] # desired
1) 我尝试用一个简单的表达式和 lambda
来实现,但结果是失败了:
tmp = sorted(tmp, key = lambda x: -tmp.count(x[0]))
2) 我通过使用 collections.Counter
达到了想要的结果:
c = collections.Counter(x[0] for x in tmp)
tmp = sorted(tmp, key = lambda x: -c[x[0]])
我的问题是:为什么第一种方法不对?有没有比第二种方法更好的选择?
1 个回答
4
In [54]: tmp = [((0,0), (1,1)), ((1,2), (3,4)), ((1,2), (5,6))]
In [55]: counts = collections.Counter(t[0] for t in tmp)
In [56]: sorted(tmp, key=lambda t:counts[t[0]])
Out[56]: [((0, 0), (1, 1)), ((1, 2), (3, 4)), ((1, 2), (5, 6))]
In [57]: sorted(tmp, key=lambda t:counts[t[0]], reverse=True)
Out[57]: [((1, 2), (3, 4)), ((1, 2), (5, 6)), ((0, 0), (1, 1))]
你最开始的方法是错的,因为 x[0]
在 tmp
里并不存在。实际上,它是在 tmp
中某个元组里的第一个元素。
我稍微改进了一下你的第二种方法,这样就不需要再乘以 -1
了。
我其实不太推荐这样做,但如果你真的想让你的第一种方法有效的话,你可以统计所有以 x[0]
作为第一个元素的元组数量:
In [58]: sorted(tmp, key=lambda t:len([tup for tup in tmp if tup[0]==t[0]]), reverse=True)
Out[58]: [((1, 2), (3, 4)), ((1, 2), (5, 6)), ((0, 0), (1, 1))]