Python 标尺序列生成器
Python Ruler Sequence Generator
我想了很久如何在Python中定义一个标尺序列的生成函数,它遵循序列的第一个数字(从1开始)出现的规则一次,接下来的两个数字会出现两次,接下来的三个数字会出现三次,等等
所以我想要得到的是 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7 等。
我知道这样做的方法是有两个独立的计数生成器 (itertools.count(1)),然后对于一个生成器中的每个数字,从另一个生成器中生成数字:
def rul():
num = itertools.count(1)
repeator = itertools.count(1)
for x in range(next(repeator)):
yield from num
但是如果我在这个函数上点击 next(),我只会返回常规的 1,2,3,4.. 序列...
如有任何帮助,我们将不胜感激。
itertools.repeat
怎么样?
import itertools
def ruler():
num = rep_count = 0
while True:
rep_count += 1
for i in range(rep_count):
num += 1
yield from itertools.repeat(num, rep_count)
没有 itertools 的普通旧 python 怎么样?
def ruler():
counter = 1
n = 1
while True:
for i in range(counter):
for j in range(counter):
yield n
n += 1
counter += 1
以我的愚见,这是针对此类情况的最清晰、最直接的解决方案
您无需使用 itertools 中的 count()
和 repeat()
编写自己的函数即可获得这样的生成器:
from itertools import repeat,count
i = count(1,1)
rul = (n for r in count(1,1) for _ in range(r) for n in repeat(next(i),r))
for n in rul: print(n, end = " ")
# 1 2 2 3 3 4 4 4 5 5 5 6 6 6 7 7 7 7 8 8 8 8 9 9 9 9 10 10 10 10 11 11 ...
如果您想在 itertools
上全力以赴,您将需要 count
、repeat
和 chain
。
您可以按如下方式对序列中的数字进行分组,其中
每个组对应于 repeat
:
的单个实例
1 # repeat(1, 1)
2 2 # repeat(2, 2)
3 3 # repeat(3, 2)
4 4 4 # repeat(4, 3)
5 5 5 # repeat(5, 3)
6 6 6 # repeat(6, 3)
7 7 7 7 # repeat(7, 4)
...
所以我们可以定义ruler_numbers = chain.from_iterable(map(repeat, col1, col2))
,只要我们能适当定义col1
和col2
即可。
col1
很简单:就是 count(1)
.
col2
也不复杂多少;我们可以将它们与原始序列类似地分组:
1 # repeat(1, 1)
2 2 # repeat(2, 2)
3 3 3 # repeat(3, 3)
4 4 4 4 # repeat(4, 4)
...
我们也可以使用 chain.from_iterable
和 map
生成:
chain.from_iterable(map(repeat, count(1), count(1)))
.
最后,我们在 Python 中编写 Lisp 的最佳尝试中得到了最终结果 :)
from itertools import chain, repeat, count
ruler_numbers = chain.from_iterable(
map(repeat,
count(1),
chain.from_iterable(
map(repeat,
count(1),
count(1)))))
或者如果你想用辅助函数稍微清理一下:
def concatmap(f, *xs):
return chain.from_iterable(map(f, *xs))
ruler_numbers = concatmap(repeat,
count(1),
concatmap(repeat,
count(1),
count(1)))
我想了很久如何在Python中定义一个标尺序列的生成函数,它遵循序列的第一个数字(从1开始)出现的规则一次,接下来的两个数字会出现两次,接下来的三个数字会出现三次,等等
所以我想要得到的是 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7 等。
我知道这样做的方法是有两个独立的计数生成器 (itertools.count(1)),然后对于一个生成器中的每个数字,从另一个生成器中生成数字:
def rul():
num = itertools.count(1)
repeator = itertools.count(1)
for x in range(next(repeator)):
yield from num
但是如果我在这个函数上点击 next(),我只会返回常规的 1,2,3,4.. 序列...
如有任何帮助,我们将不胜感激。
itertools.repeat
怎么样?
import itertools
def ruler():
num = rep_count = 0
while True:
rep_count += 1
for i in range(rep_count):
num += 1
yield from itertools.repeat(num, rep_count)
没有 itertools 的普通旧 python 怎么样?
def ruler():
counter = 1
n = 1
while True:
for i in range(counter):
for j in range(counter):
yield n
n += 1
counter += 1
以我的愚见,这是针对此类情况的最清晰、最直接的解决方案
您无需使用 itertools 中的 count()
和 repeat()
编写自己的函数即可获得这样的生成器:
from itertools import repeat,count
i = count(1,1)
rul = (n for r in count(1,1) for _ in range(r) for n in repeat(next(i),r))
for n in rul: print(n, end = " ")
# 1 2 2 3 3 4 4 4 5 5 5 6 6 6 7 7 7 7 8 8 8 8 9 9 9 9 10 10 10 10 11 11 ...
如果您想在 itertools
上全力以赴,您将需要 count
、repeat
和 chain
。
您可以按如下方式对序列中的数字进行分组,其中
每个组对应于 repeat
:
1 # repeat(1, 1)
2 2 # repeat(2, 2)
3 3 # repeat(3, 2)
4 4 4 # repeat(4, 3)
5 5 5 # repeat(5, 3)
6 6 6 # repeat(6, 3)
7 7 7 7 # repeat(7, 4)
...
所以我们可以定义ruler_numbers = chain.from_iterable(map(repeat, col1, col2))
,只要我们能适当定义col1
和col2
即可。
col1
很简单:就是 count(1)
.
col2
也不复杂多少;我们可以将它们与原始序列类似地分组:
1 # repeat(1, 1)
2 2 # repeat(2, 2)
3 3 3 # repeat(3, 3)
4 4 4 4 # repeat(4, 4)
...
我们也可以使用 chain.from_iterable
和 map
生成:
chain.from_iterable(map(repeat, count(1), count(1)))
.
最后,我们在 Python 中编写 Lisp 的最佳尝试中得到了最终结果 :)
from itertools import chain, repeat, count
ruler_numbers = chain.from_iterable(
map(repeat,
count(1),
chain.from_iterable(
map(repeat,
count(1),
count(1)))))
或者如果你想用辅助函数稍微清理一下:
def concatmap(f, *xs):
return chain.from_iterable(map(f, *xs))
ruler_numbers = concatmap(repeat,
count(1),
concatmap(repeat,
count(1),
count(1)))