如何在Python中同时运行 3个计数器?
How to run 3 counters simultaneously in Python?
我想同时运行 3 个不同的计数器遵循一个非常特定的模式:
counter_3
显示从0到2144的迭代次数
counter_1
每65次迭代增加1
counter_2
从 1 到 65,然后从 2 回到 65,然后从 3 到 65 ...
结果应如下所示:
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_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)
对于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
我想同时运行 3 个不同的计数器遵循一个非常特定的模式:
counter_3
显示从0到2144的迭代次数counter_1
每65次迭代增加1counter_2
从 1 到 65,然后从 2 回到 65,然后从 3 到 65 ...
结果应如下所示:
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_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)
对于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