python中的指数退避实现

Posted

技术标签:

【中文标题】python中的指数退避实现【英文标题】:exponential backoff implementation in python 【发布时间】:2017-09-14 16:29:28 【问题描述】:

我有两个列表“开始”和“结束”。它们的长度相同(每个 400 万):

for i in xrange(0,len(start)):
      print start[i], end[i]

3000027 3000162
3000162 3000186
3000186 3000187
3000187 3005000
3005000 3005020
3005020 3005090
3007000 3007186
3007186 3009000
3009000 3009500
.......

我的问题是我想迭代两个列表,从同一点开始,但沿着“结束列表”逐步迭代,直到找到一个值,其中“开始[i]”和“结束[ i+x]' 大于 1000。

我已尽最大努力做到这一点,我使用无限循环迭代“结束列表”,直到与 start 的差异超过 1000,然后从该点开始并从那里执行相同的操作...

注意:旧内容省略

最终我正在寻找的输出是(以上面的说明图为例):

print density
  [4, 2, 1 ...........]

谁能帮我解决这个问题?

更新

虽然之前对这个问题的回答确实有效:

density=[]
i_s = 0
while i_s < len(start):
     i_e = i_s
     while i_e < len(end):
         if end[i_e] - start[i_s] > 1000:
             density.append(i_e - i_s + 1)
             i_s = i_e
             break
         i_e += 1
     i_s += 1


print sum(density)/float(len(density))
print max(density)
print min(density)

我担心代码非常慢,因为我正在更新“i_e”的扩展名,通过在内部 while 循环的每次迭代中添加 1... 为了解决这个问题,我想创建一个动态扩展“i_e”变量的“计数器”变量。这将通过递归来完成,其中 i_e 变量将以指数方式增加,直到达到所需距离的一半,然后以指数方式减少,直到达到所需距离。

策略说明

我的尝试如下:

我创建了一个递归函数来更新变量“计数器”

counter=1 ##### initialise counter with value of 1
def exponentially_increase_decrease(start, end, counter):
    distance=end-start
    if distance<=500:  ###500 is half the desired distance
        counter=exponentially_increase_decrease(start, end, counter*2)
    else:
        counter=-exponentially_increase_decrease(start, end, counter/2)
    print counter
    return counter

在原代码中调用函数:

density=[]
i_s = 0
while i_s < len(start):
     i_e = i_s
     while i_e < len(end):
         if end[i_e] - start[i_s] > 1000:
             density.append(i_e - i_s + 1)
             i_s = i_e
             break
         counter=counter=exponentially_increase_decrease(i_s, i_e, counter)
         i_e += counter
     i_s += 1

我收到以下错误:

(印刷数千次)

counter=exponentially_increase_decrease(start, end, counter*2)
RuntimeError: maximum recursion depth exceeded

我没有遇到过此类问题,并且不确定我是否正确地解决了它...有人可以帮忙吗?

【问题讨论】:

开始、结束列表都排序了吗? 为什么在while循环之后不是所有的东西都缩进了?我认为它需要。 抱歉,代码现在应该缩进,是的,两个列表都已排序 我只是不明白你想要做什么。为什么结束列表中的4005090 与开始列表中的300500 相比不满足条件? 您要寻找的输出是什么?我还是不明白。 【参考方案1】:

这是我发现while 循环更直接的少数情况之一,因为i_ei_s 相互依赖。您可以使用两个 range 迭代器,并将前者推进您从后者中消耗的数量,但这似乎过于复杂。

>>> start
[3000027, 3000162, 3000186, 3000187, 3005000, 3005020, 3007000, 3007186, 3009000]
>>> end
[3000162, 3000186, 3000187, 3005000, 3005020, 3005090, 3007186, 3009000, 3009500]
>>> i_s = 0
>>> while i_s < len(start):
...     i_e = i_s
...     while i_e < len(end):
...         if end[i_e] - start[i_s] > 1000:
...             print(i_e - i_s + 1)
...             i_s = i_e
...             break
...         i_e += 1
...     i_s += 1
...
4
3
1

【讨论】:

好吧,如果你打算使用while,你也可以将条件end[i_e] - start[i_s] &gt;= 1000移动到while,这样你就不需要break @dabadaba 嗯,也许我想多了,但是如果这个条件永远不会成立呢? 那么它会用尽我猜的列表? @dabadaba 尝试索引列表时会抛出错误...没有列表迭代器可以耗尽... 但是你已经在检查i_e &lt; len(end),它不会越界【参考方案2】:

不确定我是否理解正确...这是您要查找的内容吗?

MAX_DIFF = 1000
density = [0] * len(start)
for i in range(len(start)):
    for j in range(i, len(end)):
        density[i] += 1
        if end[i] - start[i] >= MAX_DIFF:
            break
print(density)

【讨论】:

OP 是否想在内存中存储 len(start) 列表? (s)他说这些列表有 400 万个元素长 @dabadaba 嗯,我不能确定,但​​这似乎是预期的输出?...但是,如果需要,它可以表示为生成器。

以上是关于python中的指数退避实现的主要内容,如果未能解决你的问题,请参考以下文章

RxJava 中的指数退避

sh Bash中的指数退避

sh Bash中的指数退避

AWS 中的错误重试和指数退避 Error Retries and Exponential Backoff in AWS

python 指数退避。

python 指数退避。