如何在Python中同时运行 3个计数器?

How to run 3 counters simultaneously in Python?

我想同时运行 3 个不同的计数器遵循一个非常特定的模式:

结果应如下所示:

counter_1   counter_2   counter_3

    0          1            0
    0          2            1
    0          3            2
    0          4            3
    0          5            4
    ...        ...          ...
    0          65           64
    1          2            65
    1          3            66
    1          4            67
    ...        ...          ...
    1          65           128
    1          3            129
    2          4            130
    2          5            131
    ...        ...          ...
    32         64           2142
    32         65           2143
    32         65           2144

我知道如何分别 运行 这些计数器。

对于counter_1counter_3(以下称为i):

counter_1 = 0

for i, e in enumerate(range(2145)):
        if i > 1 and i % 65 == 0:
            counter_1 += 1
        print(counter_1, i)

对于counter_2(以下简称e):

n = 0
g = 1
while n <= 2145:
    for e in np.arange(g, 66):
        print(e)   
    g += 1
    n += 1

问题:我怎样才能同时 运行 这 3 个计数器?

您的总体思路是正确的:确定何时必须 fiddle 使用计数器。但是,请注意 coutner1 是一个您可以通过整数除法从 counter3 中简单导出的值。只要担心 counter2,你就没事了。这是更适合您编码水平的解决方案:

c2 = 65
c2_new = 0   # Track where to start counter2 next time

for c3 in range(2145):

    if c2 == 65:
        c2 = c2_new
        c2_new += 1

    c2 += 1
    c1 = c3 // 65   # Simple division gets the c1 value

    print c1, c2, c3

第三个计数器只是索引,第一个计数器是 index/65。只有中间的计数器不那么琐碎,所以我会用它来驱动它。

for c, b in enumerate(b for start in range(1, 66) for b in range(start, 66)):
    print c / 65, b, c

还有一个 itertools 版本:

for c, (_, b) in enumerate(combinations(range(66), 2)):
    print c / 65, b, c

我不是在为您的问题寻找最简单或最巧妙的具体答案,我想提供一个可以更广泛应用的模式。

您可以使用生成器提供所需的每个数字系列,然后将它们组合起来。这意味着您可以独立测试它们。这也意味着您可以对它们中的每一个进行参数化,以允许在测试期间使用更小的数字。例如,在这里,Counter_1 被参数化,因此在其行为改变之前允许重复的次数。

Counter_2 几乎肯定比它需要的更复杂。我脑子里一片迷雾。

def Counter_1(rep=65):
    n = -1
    while True:
        n += 1
        k = n//rep
        yield k

def Counter_2(rep=65):
    n = 0
    inc = 0
    while True:
        n += 1
        if n==rep:
            k = n//rep
            yield n
            inc += 1
            n = inc
        else:
            yield n

counter_1 = Counter_1()
counter_2 = Counter_2()

for counter_3 in range(2145):
    c_1 = next(counter_1)
    c_2 = next(counter_2)
    print (c_1, c_2, counter_3)

    if counter_3>10:
        break

另一种使用生成器函数的迭代方法(在 Python 3 中)。

代码

import itertools as it


def counter1(item=0):
    """Yield increments every 65 iterations."""
    for _ in range(1, 66):
        yield item
    yield from counter1(item+1)


def counter2(item=1, stop=66):
    """Yield `item` to 65, incrementing `item` after `stop-1`."""
    yield from range(item, stop)
    if item != stop:
        yield from counter2(item+1)


def counter3(stop=2150-5):
    """Yield numbers 0 to `stop`."""
    for item in range(stop):
        yield item


cts = list(zip(counter1(), counter2(), counter3()))

演示

# Sample results (see OP results)
counters = it.chain(cts[:5], cts[63:68], cts[128:132], cts[-3:])
for iteration in counters:
    print("{:<10} {:<10} {:<10}".format(*iteration))

示例输出

0          1          0         
0          2          1         
0          3          2         
0          4          3         
0          5          4         
0          64         63        
0          65         64        
1          2          65        
1          3          66        
1          4          67        
1          65         128       
1          3          129       
2          4          130       
2          5          131       
32         64         2142      
32         65         2143      
32         65         2144  

详情

  • counter1:一个无限生成器;产生超过一定范围的数字的值。递归地重复递增的值。
  • counter2:一个无限生成器;对于每次迭代,从一个范围内产生一个值。递归地重复增加的计数器。
  • counter3:一个有限生成器; range().
  • 的简单迭代

生成的计数器被压缩在一起,在有限的counter3终止后耗尽。

此示例在将 yield from 语句转换为 for 循环后兼容 Python 2,例如

for i in range(x, stop):
    yield i