小编典典

计算元组列表中项目的频率

python

我有一个元组列表,如下所示。我必须计算有多少个项目的数字大于1。到目前为止,我编写的代码非常慢。即使大约有1万个元组,如果您在下面看到示例字符串出现两次,因此我也必须获得这种字符串。我的问题是,通过遍历生成器来实现此处的字符串计数的最佳方法是什么

清单:

 b_data=[('example',123),('example-one',456),('example',987),.....]

到目前为止,我的代码:

blockslst=[]
for line in b_data:
    blockslst.append(line[0])

blocklstgtone=[]
for item in blockslst:
    if(blockslst.count(item)>1):
        blocklstgtone.append(item)

阅读 208

收藏
2021-01-16

共1个答案

小编典典

您有从每个元组中提取第一项的正确想法。您可以使用列表/生成器理解来使代码更简洁,如下所示。

从那时起,查找元素频率计数的最惯用的方式是使用collections.Counter对象。

  1. 从元组列表中提取第一个元素(使用理解)
  2. 传递给 Counter
  3. 查询数 example

    from collections import Counter

    counts = Counter(x[0] for x in b_data)
    print(counts[‘example’])

当然,list.count如果您只是要查找频率计数的 一项 ,则可以使用,但是在通常情况下,aCounter是一种解决方法。


a的优势Counter在于,它可以在线性()时间内对 所有
元素(不仅仅是example)执行频率计数O(N)。假设您还想查询另一个元素的计数,例如foo。那可以用-

print(counts['foo'])

如果'foo'列表中不存在,0则返回。

如果要查找最常见的元素,请致电counts.most_common-

print(counts.most_common(n))

n您要显示的元素数量在哪里。如果您想看一切,请不要错过n


要检索最常见元素的计数,一种有效的方法是查询most_common,然后使用提取所有计数超过1的元素itertools

from itertools import takewhile

l = [1, 1, 2, 2, 3, 3, 1, 1, 5, 4, 6, 7, 7, 8, 3, 3, 2, 1]
c = Counter(l)

list(takewhile(lambda x: x[-1] > 1, c.most_common()))
[(1, 5), (3, 4), (2, 3), (7, 2)]

(OP编辑)或者,使用 列表推导 获取计数> 1的项目列表-

[item[0] for item in counts.most_common() if item[-1] > 1]

请记住,这没有itertools.takewhile解决方案那么有效。例如,如果您有一个计数大于1的项目,而一百万个计数等于1的项目,则最终不必重复遍历列表一百万次(因为most_common返回频率计数)降序排列)。随着takewhile事实并非如此,因为你一旦停止迭代作为计数的条件>
1为假。

2021-01-16