Python直方图一线

发布于 2021-01-29 18:36:06

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

所谓直方图,是指一个函数,该函数计算an中对象的出现iterable并在字典中输出计数。例如:

>>> L = 'abracadabra'
>>> histogram(L)
{'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r': 2}

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

def histogram(L):
    d = {}
    for x in L:
        if x in d:
            d[x] += 1
        else:
            d[x] = 1
    return d

有没有更简洁的编写此功能的方法?

如果我们在Python中具有字典理解功能,则可以编写:

>>> { x: L.count(x) for x in set(L) }

但是由于Python 2.6没有它们,我们必须编写:

>>> dict([(x, L.count(x)) for x in set(L)])

尽管此方法可能可读,但效率不高:L多次遍历。此外,这不适用于单寿命发电机。该功能对于迭代器生成器应同样有效,例如:

def gen(L):
    for x in L:
        yield x

我们可能会尝试使用reduce功能(RIP):

>>> reduce(lambda d,x: dict(d, x=d.get(x,0)+1), L, {}) # wrong!

糟糕,这行不通:键名是'x',不是x。:(

我以:

>>> reduce(lambda d,x: dict(d.items() + [(x, d.get(x, 0)+1)]), L, {})

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

请用更好的,更具可读性的单线打败我!;)

关注者
0
被浏览
53
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

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

    Python
    2.7和3.x还具有一个Counter类,该类可以完全满足您的要求:

    from collections import Counter
    cnt = Counter("abracadabra")
    

    在Python
    2.6或更早版本中,我个人使用defaultdict并分两行进行:

    d = defaultdict(int)
    for x in xs: d[x] += 1
    

    那是干净,高效,Python式的,对于大多数人而言,它比涉及任何东西都容易理解reduce



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看