4

我想知道如何对列表中的类似值进行排序,然后将类似的值分解为子列表。

例如:我想要一个可能做类似事情的函数

def sort_by_like_values(list):
    #python magic

>>>list=[2,2,3,4,4,10]
>>>[[2,2],[3],[4,4],[10]]
OR
>>>[2,2],[3],[4,4],[10]

我阅读了 sorted api,它可以很好地在他们自己的列表中进行排序,但不会将列表分解为子列表。什么模块可以帮助我?

4

5 回答 5

5

groupby从 itertools 模块使用。

from itertools import groupby

L = [2, 2, 3, 4, 4, 10]

L.sort()
for key, iterator in groupby(L):
    print key, list(iterator)

结果:

2 [2, 2]
3 [3]
4 [4, 4]
10 [10]

需要注意的几件事:groupby需要按照您希望分组的相同键对它处理的数据进行排序,否则它将不起作用。此外,在继续下一组之前需要使用迭代器,因此请确保存储list(iterator)到另一个列表或其他内容。一条线为您提供您想要的结果:

>>> [list(it) for key, it in groupby(sorted(L))]
[[2, 2], [3], [4, 4], [10]]
于 2012-07-21T20:59:08.057 回答
2

检查itertools模块,它具有有用的groupby功能:

import itertools as i
for k,g in i.groupby(sorted([2,2,3,4,4,10])):
    print list(g)

....

[2, 2]
[3]
[4, 4]
[10]

您应该能够修改它以获取列表中的值。

于 2012-07-21T20:59:43.103 回答
2

正如其他人所建议的那样itertools.groupby(这将是我的第一选择) - 也可以collections.Counter获取密钥和频率,按密钥排序,然后扩展频率时间。

from itertools import repeat
from collections import Counter

grouped = [list(repeat(key, freq)) for key, freq in sorted(Counter(L).iteritems())]
于 2012-07-21T21:21:18.663 回答
1

如果您不想使用 itertools 并且可以将您的头脑围绕在列表推导上,这也应该可以解决问题:

def group(a):
    a = sorted(a)
    d = [0] + [x+1 for x in range(len(a)-1) if a[x]!=a[x+1]] + [len(a)]
    return [a[(d[x]):(d[x+1])] for x in range(len(d)-1)]

a你的清单在哪里

于 2012-07-21T21:57:36.927 回答
1

itertools.groupby()使用列表理解可以正常工作。

In [20]: a = [1, 1, 2, 3, 3, 4, 5, 5, 5, 6]

In [21]: [ list(subgroup) for key, subgroup in itertools.groupby(sorted(a)) ]
Out[21]: [[1, 1], [2], [3, 3], [4], [5, 5, 5], [6]]

请注意,它groupby()返回一个迭代器列表,您必须按顺序使用这些迭代器。根据文档:

返回的组本身就是一个迭代器,它与 groupby() 共享底层迭代。因为源是共享的,所以当 groupby() 对象前进时,之前的组不再可见。因此,如果以后需要该数据,则应将其存储为列表:

于 2012-07-21T21:04:35.203 回答