计算部分列表出现次数的最快方法

2024-04-27 05:05:24 发布

您现在位置:Python中文网/ 问答频道 /正文

从开始位置到停止位置,计算图元出现次数的最快方法是什么

 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函数,但是由于列表很大,转换为字符串似乎不是一种更快的方法

有没有更快捷的方法来实现这一点


Tags: 方法函数字符串列表countcounterbesymbol
3条回答

试试这个:

from collections import Counter
print(Counter(my_list[start:end]))

如果愿意,您可以将Counter对象转换为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是否在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

如果你只测试了列表中的一小部分,这可能会更快,也可能不会更快。如果你测试了列表中的最后一个元素,这不会有多大作用,但是如果你的列表很大,并且你的目标区域是“前面”的话,那么这个中断可能会为你节省一些周期

如果您想要纯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))

相关问题 更多 >