Python 列表按组的大小排序

标签 python python-2.6 python-itertools sorting

我有一组标记为 item_labels = [('a', 3), ('b', 2), ('c', 1), ('d', 3) , ('e', 2), ('f', 3)]

我想按组的大小对它们进行排序。例如,在上例中,标签 3 的尺寸为 3,标签 2 的尺寸为 2。

我尝试结合使用 groupbysorted 但没有成功。

In [162]: sil = sorted(item_labels, key=op.itemgetter(1))

In [163]: sil
Out[163]: [('c', 1), ('b', 2), ('e', 2), ('a', 3), ('d', 3), ('f', 3)]

In [164]: g = itt.groupby(sil,)
Display all 465 possibilities? (y or n)

In [164]: g = itt.groupby(sil, key=op.itemgetter(1))

In [165]: for k, v in g:
   .....:     print k, list(v)
   .....:
   .....:
1 [('c', 1)]
2 [('b', 2), ('e', 2)]
3 [('a', 3), ('d', 3), ('f', 3)]

In [166]: sg = sorted(g, key=lambda x: len(list(x[1])))

In [167]: sg
Out[167]: [] # not exactly know why I got an empty list here

我总是可以写一些乏味的 for 循环来做到这一点,但我宁愿找到更优雅的东西。有什么建议吗?如果有有用的库,我会很乐意使用它。例如,pandasscipy

最佳答案

在python2.7及以上,使用Counter:

from collections import Counter
c = Counter(y for _, y in item_labels)
item_labels.sort(key=lambda t : c[t[1]])

在 python2.6 中,出于我们的目的,可以使用 defaultdict(如@perreal 所建议的那样)以这种方式实现此 Counter 构造函数:

from collections import defaultdict
def Counter(x):
    d = defaultdict(int)
    for v in x: d[v]+=1
    return d

由于我们只处理数字,并且假设数字与您的示例中的数字一样低,我们实际上可以使用列表(它将与甚至更旧版本的 Python 兼容):

def Counter(x):
    lst = list(x)
    d = [0] * (max(lst)+1)
    for v in lst: d[v]+=1
    return d

没有计数器,你可以简单地这样做:

item_labels.sort(key=lambda t : len([x[1] for x in item_labels if x[1]==t[1] ]))

它较慢,但在短列表上是合理的。


你得到一个空列表的原因是 g 是一个生成器。您只能迭代一次。

关于Python 列表按组的大小排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17285525/

相关文章:

Python 脚本作为子进程调用时无法导入已安装的模块

python - 在 Python 中随机选择所有组合的子集

python - itertools.product 消除重复元素

python - 类实例作为静态属性

python - Celery: '|' 运算符在链接多任务时如何工作?

python - 如何优化 Python 中大型(75,000 项) bool 值集的操作?

python - Cython:将 unicode 字符串转换为 wchar 数组

Python:使用 "yield"生成树

python - 没有模块名称 'sklearn.forest.ensemble'

python - 选择多于 C 列中值大于 V 的行