[英]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_1
和counter_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. counter2
: an infinite generator; counter2
: 无限生成器; for every iteration, yield a value from a range. 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.