我认为列表推导可能会给我这个,但我不确定: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
是我的对象定义中的(字符串)列表。
答案 0 :(得分:11)
Lennart Regebro provided a nice one-liner做你想做的事:
>>> values = [1,1,1,2]
>>> print [(x,values.count(x)) for x in set(values)]
[(1, 3), (2, 1)]
As S.Lott mentions,defaultdict可以做同样的事情。
答案 1 :(得分:11)
>>> from collections import Counter
>>> Counter([1,1,1,2])
Counter({1: 3, 2: 1})
Counter仅在py3.1中可用,继承自dict
。
答案 2 :(得分:6)
作为列表理解并不容易。
from collections import defaultdict
def group_by( someList ):
counts = defaultdict(int)
for value in someList:
counts[value.aKey] += 1
return counts
这是一个非常Pythonic的解决方案。但不是列表理解。
答案 3 :(得分:4)
您可以使用itertools
模块中的groupby
:
创建一个迭代器,从迭代中返回连续的键和组。关键是计算每个元素的键值的函数。如果未指定或为None,则键默认为标识函数并返回元素不变。通常,迭代需要已经在相同的键函数上排序。
>>> a = [1,1,1,2]
>>> [(len(list(v)), key) for (key, v) in itertools.groupby(sorted(a))]
[(3, 1), (1, 2)]
我认为它的运行时比SilentGhost或S.Lott的基于dict
的解决方案更差,因为它必须对输入序列进行排序,但你应该自己计时。不过,这是列表理解。它应该比Adam Bernier的解决方案更快,因为它不必对输入序列进行重复的线性扫描。如果需要,可以通过在线排序输入序列来避免sorted
调用。
答案 4 :(得分: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"