A = [1,1,1,2,4]
count = []
freq = 0
#ranges = [[1, 6], [1, 6], [1, 6], [2, 7], [4, 9]]
for i in A :
if (i >= ranges[i][0] and i <= ranges[i][1]):
freq = freq + 1
count.append(freq)
我的计数应该是5,5,5,2,1 (因为在0-5范围内有5个数字,1-6中有5个数字,2-7中有2个数字,4-9中有1个数字。但是我的计数是返回1,2,3,4,5,我假设每次循环都会加1,但是我找不到错误所在。
编辑:我不能迭代范围,因为必须符合O(n),并且不允许导入字典:(
发布于 2021-03-14 20:31:44
如果你想要简单的Python循环:
count = [sum([a >= r0 and a <= r1 for a in A]) for r0, r1 in ranges]
但是,如果您正在寻找比显式Python循环快得多的东西,我建议您使用numpy
A = [1,1,1,2,4]
ranges = [[1, 6], [1, 6], [1, 6], [2, 7], [4, 9]]
a = np.array(A)[:, None]
r = np.array(ranges)
((a >= r[:,0]) & (a <= r[:,1])).sum(axis=0)
提供:
array([5, 5, 5, 2, 1])
附注
Python中“范围”的通常含义是左封闭和右开放:range(a, b)
包含a
,但不包含b
(正如自然所希望的那样)。您的代码似乎表明您正在寻找右闭合区间,所以我在下面的答案中模仿了这一点。如果您改变主意,可以将<=
修改为<
。
速度
def fun(A, ranges):
r = np.array(ranges)
a = np.array(A)[:, None]
return ((a >= r[:,0]) & (a <= r[:,1])).sum(axis=0)
n, m = 10_000, 100 # 2M comparisons
A = np.random.randint(0, 100, size=m)
ranges = np.random.randint(0, 100, size=(n, 2))
d0 = %timeit -o fun(A, ranges)
# 2.25 ms ± 3.24 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
d1 = %timeit -o [sum([a >= r0 and a <= r1 for a in A]) for r0, r1 in ranges]
# 2.03 s ± 6.88 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
d1.average / d0.average
# 899x speedup
发布于 2021-03-14 20:36:50
通过将ranges
中每个列表中的值作为参数传递给range()
函数,这应该是可行的。
A = [1,1,1,2,4]
count = []
freq = 0
ranges = [[1, 6], [1, 6], [1, 6], [2, 7], [4, 9]]
for r in ranges :
count.append(sum([x in range(*r) for x in A]))
print(count) # --> [5, 5, 5, 2, 1]
发布于 2021-03-14 21:21:54
这是修改dgcode的答案:
from collections import Counter
A = [1,1,1,2,4]
c = Counter(A)
sc = set(c)
count = []
freq = 0
ranges = [[1, 6], [1, 6], [1, 6], [2, 7], [4, 9]]
for r in ranges :
count.append(sum(c[i] for i in set(range(*r))&sc))
print(count) # --> [5, 5, 5, 2, 1]
https://stackoverflow.com/questions/66624337
复制相似问题