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

min*_*bro 14 python tuples list generator python-3.x

我有一个元组列表,如下所示.我必须计算有多少项的数字大于1.我到目前为止编写的代码非常慢.即使有大约10K元组,如果你看到下面的例子字符串出现两次,所以我必须得到这样的字符串.我的问题是通过迭代生成器来实现字符串计数的最佳方法是什么

列表:

 b_data=[('example',123),('example-one',456),('example',987),.....]
Run Code Online (Sandbox Code Playgroud)

我的代码到目前为止:

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

blocklstgtone=[]
for item in blockslst:
    if(blockslst.count(item)>1):
        blocklstgtone.append(item)
Run Code Online (Sandbox Code Playgroud)

cs9*_*s95 14

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

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

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

counts = Counter(x[0] for x in b_data)
print(counts['example'])
Run Code Online (Sandbox Code Playgroud)

当然,你可以使用list.count它只是你想要找到频率计数的一个项目,但在一般情况下,a Counter是要走的路.


a的优点Counter是它在线性()时间内执行所有元素(不仅仅是example)的频率计数O(N).比如说,你也想查询另一个元素的数量foo.那可以用 -

print(counts['foo'])
Run Code Online (Sandbox Code Playgroud)

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

如果您想找到最常见的元素,请致电counts.most_common-

print(counts.most_common(n))
Run Code Online (Sandbox Code Playgroud)

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)]
Run Code Online (Sandbox Code Playgroud)

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

[item[0] for item in counts.most_common() if item[-1] > 1]
Run Code Online (Sandbox Code Playgroud)

请记住,这不如itertools.takewhile解决方案有效.例如,如果你有一个count> 1的项目和一百万个count等于1的项目,那么当你不需要时,你最终会在列表上迭代一百万次(因为most_common返回频率计数)按降序排列).随着takewhile事实并非如此,因为你停止作为计数的条件> 1为假尽快迭代.