Python 计算部分列表出现次数的最快方法
从开始位置到停止位置,计算图元出现次数的最快方法是什么Python 计算部分列表出现次数的最快方法,python,python-3.x,list,performance,Python,Python 3.x,List,Performance,从开始位置到停止位置,计算图元出现次数的最快方法是什么 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:endpo
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)
但是,这看起来仍然比第一个选项慢,并且将复制列表的很大一部分
由于字符串有这样一个count函数,我们可以将列表连接到一个字符串,然后使用内置的count函数,但是由于列表很大,转换为字符串似乎不是一种更快的方法
有没有更快捷的python方法来实现这一点?试试这个:
from collections import Counter
print(Counter(my_list[start:end]))
如果愿意,您可以将计数器
对象转换为dict:
occurrences = dict(Counter(my_list[start:end]))
试试这个:
from collections import Counter
print(Counter(my_list[start:end]))
如果愿意,您可以将计数器
对象转换为dict:
occurrences = dict(Counter(my_list[start:end]))
您可以使用生成器和范围来检查枚举索引是否在您的范围内:
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
是否在范围内是快速的
展开循环将有助于休息-如果快速性非常关键,你应该计时你的方法:
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
maxpos=max(pos)
最小位置=最小(位置)
对于idx,枚举(d)中的元素:
如果idxpos:
打破
#查一查元素,数一数
持续
如果您只测试列表中的一小部分,这可能会更快,也可能不会更快。如果您测试列表中的最后一个元素,这不会有多大作用,但是如果您的列表很大,并且您的目标区域是“最前面”的,则中断可能会为您节省一些周期您可以使用生成器和范围来检查枚举索引是否在您的范围内:
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
是否在范围内是快速的
展开循环将有助于休息-如果快速性非常关键,你应该计时你的方法:
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
maxpos=max(pos)
最小位置=最小(位置)
对于idx,枚举(d)中的元素:
如果idxpos:
打破
#查一查元素,数一数
持续
如果您只测试列表中的一小部分,这可能会更快,也可能不会更快。如果您测试列表中的最后一个元素,这不会有多大作用,但是如果您的列表很大,并且您的目标区域是“最前面”的话,如果您想要一个纯Python解决方案,中断可能会为您节省一些周期,将第一个选项转换为sum
函数中的生成器表达式可能是非常大的列表的最有效解决方案:
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))
如果您想要纯Python解决方案,将第一个选项转换为sum
函数中的生成器表达式可能是非常大的列表的最有效的解决方案:
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))
lst[start:end].count(elem)
比enumerate
版本更好更快(几乎是10倍,但我想这取决于范围),但您的替代方案与list[start:end].count一样,没有额外的空间。“更好更快”取决于您提供的数据。如果在5.2个数据点的子列表中有50亿个数据点,那么复制这50亿个数据点并随后计数可能比迭代它们的成本更高-这就是为什么我提到了timeit
-ing它。为了便于阅读和良好的C++实现,复制.CONTUTE()变量可能是我要进行的99/100次。问题的前提是一个很长的列表,因此,如果所需的范围接近列表的末尾,那么从列表的开头进行迭代可能会非常低效,因为循环会浪费在范围之外的迭代中。完全同意。当数据非常大的时候。我会使用您提到的第二种方法,或者首先使用NumPy数组来处理如此大的数据。@blh您使用生成器和的方式更好:)lst[start:end]。count(elem)
比enumerate
version更好更快(几乎是10倍,但我想这取决于范围)但是,您的替代方案与列表[start:end].count相同,没有额外的空间。“更好更快”取决于您提供的数据。如果在5.2个数据点的子列表中有50亿个数据点,那么复制这50亿个数据点并随后计数可能比迭代它们的成本更高-这就是为什么我提到了timeit
-ing它。为了便于阅读和良好的C++实现,复制.CONTUTE()变量可能是我要进行的99/100次。问题的前提是一个很长的列表,因此,如果所需的范围接近列表的末尾,那么从列表的开头进行迭代可能会非常低效,因为循环会浪费在范围之外的迭代中。完全同意。当数据非常大的时候。我会的