Python的列表推导(理想情况下)可以在SQL中执行相当于'count(*)... group by ...'的操作吗?

mon*_*nny 5 python list count python-2.6

我认为列表推导可能会给我这个,但我不确定: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;
Run Code Online (Sandbox Code Playgroud)

这使:

COUNT(*) n
==========
3        1
1        2
Run Code Online (Sandbox Code Playgroud)

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

[1,1,1,2]
Run Code Online (Sandbox Code Playgroud)

我想要与上面给出的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)
Run Code Online (Sandbox Code Playgroud)

__hash__需要使用该方法才能使set转换工作(我选择了在2.6中工作的列表理解思想[尽管事实上我知道这涉及效率低下(参见注释) - 我的数据集足够小,因为它不是问题]).my_list_of_stuff上面是我的对象定义中的(字符串)列表.

ber*_*nie 11

Lennart Regebro提供了一个很棒的单行程,可以满足您的需求:

>>> values = [1,1,1,2]
>>> print [(x,values.count(x)) for x in set(values)]
[(1, 3), (2, 1)]
Run Code Online (Sandbox Code Playgroud)

正如S.Lott所提到的,默认指令可以做同样的事情.

  • defaultdict解决方案在较大的`values`列表上会做得更好,因为它只会循环一次值,而不是每个唯一值一次加一次. (3认同)

Sil*_*ost 11

>>> from collections import Counter
>>> Counter([1,1,1,2])
Counter({1: 3, 2: 1})
Run Code Online (Sandbox Code Playgroud)

计数器仅在py3.1中可用,继承自dict.


S.L*_*ott 6

作为列表理解不容易实现.

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

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

  • @monojohnny:`>>>来自collections import defaultdict` (2认同)

Tor*_*rek 5

您可以groupbyitertools模块中使用:

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

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

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