首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >python直方图一行

python直方图一行
EN

Stack Overflow用户
提问于 2010-05-20 09:15:40
回答 9查看 54.9K关注 0票数 47

有许多方法可以编写计算直方图的Python程序。

直方图是指对iterable中对象的出现次数进行计数并在字典中输出计数的函数。例如:

代码语言:javascript
复制
>>> L = 'abracadabra'
>>> histogram(L)
{'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r': 2}

编写此函数的一种方法是:

代码语言:javascript
复制
def histogram(L):
    d = {}
    for x in L:
        if x in d:
            d[x] += 1
        else:
            d[x] = 1
    return d

有没有更简洁的方法来编写这个函数?

如果我们在Python中有字典理解,我们可以这样写:

代码语言:javascript
复制
>>> { x: L.count(x) for x in set(L) }

但是由于Python2.6没有它们,我们必须这样写:

代码语言:javascript
复制
>>> dict([(x, L.count(x)) for x in set(L)])

尽管这种方法可能是可读的,但它的效率并不高:l被遍历多次。此外,这不适用于单生命生成器;该函数应该同样适用于迭代器生成器,例如:

代码语言:javascript
复制
def gen(L):
    for x in L:
        yield x

我们可以尝试使用reduce函数(R.I.P.):

代码语言:javascript
复制
>>> reduce(lambda d,x: dict(d, x=d.get(x,0)+1), L, {}) # wrong!

哦,这不起作用:密钥名是'x',而不是x。:(

我以如下方式结束:

代码语言:javascript
复制
>>> reduce(lambda d,x: dict(d.items() + [(x, d.get(x, 0)+1)]), L, {})

(在Python3中,我们必须编写list(d.items())而不是d.items(),但这是假设的,因为那里没有reduce。)

请用更好、更易读的一行程序击败我!;)

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2010-05-20 09:33:22

Python3.x确实有reduce,你只需要做一个from functools import reduce。它还具有“字典理解”,其语法与示例中的语法完全相同。

Python2.7和3.x也有一个Counter类,它可以执行您想要的操作:

代码语言:javascript
复制
from collections import Counter
cnt = Counter("abracadabra")

在Python2.6或更早的版本中,我个人会使用defaultdict并用两行代码来完成:

代码语言:javascript
复制
d = defaultdict(int)
for x in xs: d[x] += 1

这是干净的、高效的、Pythonic式的,而且对大多数人来说比涉及reduce的任何东西都更容易理解。

票数 76
EN

Stack Overflow用户

发布于 2010-08-18 12:47:10

为单行程序导入模块有点欺骗,所以这里有一个单行程序,它是O(n),并且至少可以追溯到Python2.4

代码语言:javascript
复制
>>> f=lambda s,d={}:([d.__setitem__(i,d.get(i,0)+1) for i in s],d)[-1]
>>> f("ABRACADABRA")
{'A': 5, 'R': 2, 'B': 2, 'C': 1, 'D': 1}

如果您认为__方法很老套,您可以随时这样做

代码语言:javascript
复制
>>> f=lambda s,d=lambda:0:vars(([setattr(d,i,getattr(d,i,0)+1) for i in s],d)[-1])
>>> f("ABRACADABRA")
{'A': 5, 'R': 2, 'B': 2, 'C': 1, 'D': 1}

:)

票数 7
EN

Stack Overflow用户

发布于 2010-11-18 10:33:42

代码语言:javascript
复制
$d{$_} += 1 for split //, 'abracadabra';
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2870466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档