我有一个元组列表,如下所示。我必须计算有多少个项目的数字大于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)
您有从每个元组中提取第一项的正确想法。您可以使用列表/生成器理解来使代码更简洁,如下所示。
从那时起,查找元素频率计数的最惯用的方式是使用collections.Counter对象。
collections.Counter
Counter
查询数 example
example
from collections import Counter
counts = Counter(x[0] for x in b_data) print(counts[‘example’])
当然,list.count如果您只是要查找频率计数的 一项 ,则可以使用,但是在通常情况下,aCounter是一种解决方法。
list.count
a的优势Counter在于,它可以在线性()时间内对 所有 元素(不仅仅是example)执行频率计数O(N)。假设您还想查询另一个元素的计数,例如foo。那可以用-
O(N)
foo
print(counts['foo'])
如果'foo'列表中不存在,0则返回。
'foo'
0
如果要查找最常见的元素,请致电counts.most_common-
counts.most_common
print(counts.most_common(n))
n您要显示的元素数量在哪里。如果您想看一切,请不要错过n。
n
要检索最常见元素的计数,一种有效的方法是查询most_common,然后使用提取所有计数超过1的元素itertools。
most_common
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为假。
itertools.takewhile
takewhile