5

我认为列表推导可能会给我这个,但我不确定:Python(2.6)中的任何优雅解决方案通常用于选择列表中的唯一对象并提供计数?

(我已经定义了一个__eq__来定义我的对象定义的唯一性)。

所以在 RDBMS-land 中,是这样的:

CREATE TABLE x(n NUMBER(1));
INSERT INTO x VALUES(1);
INSERT INTO x VALUES(1);
INSERT INTO x VALUES(1);
INSERT INTO x VALUES(2);

SELECT COUNT(*), n FROM x
GROUP BY n;

这使:

COUNT(*) n
==========
3        1
1        2

所以,这是我在 Python 中的等效列表:

[1,1,1,2]

我想要与上面给出的 SQL SELECT 相同的输出。

编辑:我在这里给出的例子被简化了,我实际上正在处理用户定义的对象实例列表:为了完整起见,我包括了让整个事情正常工作所需的额外代码:

import hashlib

def __hash__(self):
    md5=hashlib.md5()
    [md5.update(i) for i in self.my_list_of_stuff]
    return int(md5.hexdigest(),16)

需要该__hash__方法才能使set转换正常工作(我选择了在 2.6 中有效的列表理解想法 [尽管我了解到这涉及效率低下(见评论)-我的数据集足够小而不是问题])。my_list_of_stuff以上是我的对象定义中的(字符串)列表。

4

5 回答 5

11

Lennart Regebro 提供了一个很好的单线,可以满足您的需求:

>>> values = [1,1,1,2]
>>> print [(x,values.count(x)) for x in set(values)]
[(1, 3), (2, 1)]

正如 S.Lott 提到的,一个 defaultdict 可以做同样的事情。

于 2010-01-27T16:25:17.817 回答
11
>>> from collections import Counter
>>> Counter([1,1,1,2])
Counter({1: 3, 2: 1})

Counter仅在 py3.1 中可用,继承自dict.

于 2010-01-27T16:28:14.790 回答
6

作为列表理解并不容易。

from collections import defaultdict
def group_by( someList ):
    counts = defaultdict(int)
    for value in someList:
        counts[value.aKey] += 1
    return counts

这是一个非常 Pythonic 的解决方案。但不是列表理解。

于 2010-01-27T16:23:21.180 回答
5

您可以groupbyitertools模块中使用:

创建一个从可迭代对象返回连续键和组的迭代器。键是计算每个元素的键值的函数。如果未指定或为 None,则 key 默认为标识函数并返回未更改的元素。通常,iterable 需要已经在相同的 key 函数上排序。

>>> a = [1,1,1,2]
>>> [(len(list(v)), key) for (key, v) in itertools.groupby(sorted(a))]
[(3, 1), (1, 2)]

我认为它的运行时间比dictSilentGhost 或 S.Lott 的基于 - 的解决方案差,因为它必须对输入序列进行排序,但你应该自己计时。不过,这是一个列表理解。它应该比 Adam Bernier 的解决方案更快,因为它不必对输入序列进行重复的线性扫描。如果需要,sorted可以通过在线排序输入序列来避免调用。

于 2010-01-27T16:33:54.840 回答
1

以下适用于 Python 2.4,因此应该适用于 Python 2.6:

lst = [1,1,2,2,3,4,5,6,5]
lst_tmp = []
lst_dups = []

for item in lst:
    if item in lst_tmp:
        lst_dups.append(item)
    else:
        lst_tmp.append(item)

if len(lst_dups):
    lst_dups = sorted(set(lst_dups))
    for item in lst_dups:
        print str(lst.count(item)), "instances of", item
else:
    print "list is unique"
于 2011-08-26T19:17:49.280 回答