简体   繁体   English

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

[英]How to run 3 counters simultaneously in Python?

I'd like to run simultaneously 3 different counters following a very specific pattern: 我想按照一个非常特定的模式同时运行3个不同的计数器:

  • counter_3 displays the number of iteration from 0 to 2144 counter_3显示从0到2144的迭代次数
  • counter_1 increases by 1 every 65 iterations counter_1每65次迭代增加1
  • counter_2 goes from 1 to 65, then starts back from 2 to 65, then from 3 to 65 ... counter_2从1到65,然后从2到65,然后从3到65 ...

The result should look like this: 结果应如下所示:

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

I know how to run these counters separately. 我知道如何分别运行这些计数器。

For counter_1 and counter_3 (refered below as i ): 对于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)

For counter_2 (refered below as e ): 对于counter_2 (以下称为e ):

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

QUESTION: How can i run these 3 counters simultaneously ? 问题:如何同时运行这三个计数器?

You have the right general idea: determine when you have to fiddle with the counters. 您有正确的总体思路:确定何时必须摆弄柜台。 However, note that coutner1 is a value you can derive simply from counter3 with integer division. 但是,请注意, coutner1是您可以简单地从具有整数除法的counter3派生的值。 Just worry about counter2 , and you're fine. 只需担心counter2 ,您就可以了。 Here's a solution more at your level of coding: 以下是您所编码级别的解决方案:

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

Third counter is just the index and first counter is index/65. 第三个计数器只是索引,第一个计数器是index / 65。 Only the middle counter is a little less trivial, so I'd use that one to drive this. 只有中间的计数器不那么琐碎,所以我会用那个计数器来驱动它。

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

And an itertools version: 和itertools版本:

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

Not looking for the simplest or slickest specific answer to your question, I wanted to offer a pattern that might be applied more broadly. 我不想为您的问题寻找最简单或最巧妙的答案,我想提供一种可以更广泛地应用的模式。

You could use a generator to provide each of the series of numbers that you want, then combine them. 您可以使用生成器来提供所需的每个数字系列,然后将它们组合。 This means that you could test them independently. 这意味着您可以独立测试它们。 It also means that you could parameterise each of them to allow for smaller numbers during testing. 这也意味着您可以对每个参数进行参数设置,以在测试过程中使用较小的数字。 Here, for instance, Counter_1 is parameterised so with the number of repetitions allowed before its behaviour changes. 例如,在这里,对Counter_1进行了参数设置,以使其行为发生改变之前允许的重复次数。

Counter_2 is almost certainly more complicated than it needs to be. Counter_2几乎肯定比需要的要复杂。 My brain is in a fog. 我的大脑迷雾了。

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

Another iterative approach using generator functions (in Python 3). 另一种使用生成器函数的迭代方法(在Python 3中)。

Code

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()))

Demo 演示版

# 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))

Sample Output 样本输出

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  

Details 细节

  • counter1 : an infinite generator; counter1无限生成器; yields a value for over a range of numbers. 产生一个数字范围内的值。 Repeat for incremented values recursively. 递归地重复递增的值。
  • counter2 : an infinite generator; counter2无限生成器; for every iteration, yield a value from a range. 对于每次迭代,请产生一个范围内的值。 Repeat for incremented counters recursively. 递归重复递增计数器。
  • counter3 : a finite generator; counter3有限生成器; a simple iteration over a range() . range()的简单迭代。

The resulting counters are zipped together, exhausted after the termination of the finite counter3 . 所得的计数器将压缩在一起,在有限counter3终止后将其耗尽。

This example is Python 2 compatible after transforming yield from statements to for loops, eg 在将yield from语句转换for循环后,此示例与Python 2兼容,例如

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM