[英]fastest way to count occurrences of partial list
从开始 position 到停止 position 计算元素出现的最快方法是什么。
list = [a,b,c,c,d,c....] can be very long
count(list,c, from = 2, till = 4) = 2.
我们可以做
counter = 0
for i in range(startpos, endpos):
if symbol == list[i]:
counter+= 1
或者我们可以做
list[startpos:endpos].count(symbol)
但是,这看起来仍然比第一个选项慢,并且会复制列表的很大一部分
由于字符串有计数 function 像这样,我们可以将列表加入字符串,而不是使用内置计数功能,但是由于列表很大,转换为字符串似乎不是一种更快的方法。
有没有更快的pythonic方法来实现这一点?
如果您想要一个纯 Python 解决方案,将您的第一个选项转换为sum
function 中的生成器表达式对于非常大的列表可能是最有效的解决方案:
sum(1 for i in range(startpos, endpos) if list[i] == symbol)
其他选项,例如从列表的开头进行迭代(这会浪费大量时间迭代超出所需范围)或切片(涉及创建副本),当列表非常大时,效率几乎不会那么高。
但是,如果您不介意使用numpy
,则可以创建一个numpy
数组而不是列表,这样您就可以在不复制项目的情况下对其进行切片( numpy
,然后在您创建数组时使用sum
的方法)计算切片中等于所需值的项目数:
import numpy as np
... # create your very large numpy array as lst
print(np.sum(lst[startpos:endpos] == symbol))
您可以使用生成器和范围来检查枚举索引是否在您的范围内:
a = 2
pos = range(5,15)
d = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,]
total = sum(elem == a for idx,elem in enumerate(d) if idx in pos)
print(total)
这不会复制列表,但会迭代完整的原始列表。 检查idx
是否在range
很快。
展开循环将允许休息 - 如果紧固度非常关键,您应该安排您的方法:
maxpos = max(pos)
minpos = min(pos)
for idx,elem in enumerate(d):
if idx < minpos:
continue
elif idx > pos:
break
# check elem and counts something up
continue
如果您只测试少量列表,这可能会更快,也可能不会更快 - 如果您使用列表中的最后一个元素,它不会做太多,但如果您的列表很大并且您的目标区域是“前” - 休息可能会为您节省一些周期
试试这个:
from collections import Counter
print(Counter(my_list[start:end]))
如果您愿意,可以将Counter
object 转换为 dict:
occurrences = dict(Counter(my_list[start:end]))
只是为了增加 blhsing 的答案,生成器表达式可能稍微不那么冗长:
sum(list[i] == symbol for i in range(startpos, endpos))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.