说我有一个清单:
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)不正确?还有比选择2)更好的选择吗?
答案 0 :(得分:3)
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))]