我正在尝试编写一个函数,它将输入长度L
和距离D
(两个整数> 1
)并输出符合以下参数的所有可能序列:
1
L
元素1
至D
因此,对于L = 4
和D = 2
,可能的序列是:
1 2 3 4 (distance of 1 between each consecutive element)
1 2 3 5
1 2 4 5
1 2 4 6
1 3 4 5
1 3 4 6
1 3 5 6
1 3 5 7 (distance of 2 between each consecutive element)
或者,对于L = 3
和D = 3
,可能的顺序是:
1 2 3 (distance of 1 between each consecutive element)
1 2 4
1 2 5
1 3 4
1 3 5 (distance of 2 between each consecutive element)
1 3 6
1 4 5
1 4 6
1 4 7 (distance of 3 between each consecutive element)
通过手动编码其中的几个,可能的序列数似乎是D ** (L-1)
。起初我只需要2\**7
,并且128个序列并不难以手工创建。但是,我现在需要3**7
,甚至可能需要更大的数量,所以我需要编写一个函数。
Python是我正在学习的语言。递归似乎是这样做的方法,但我只是在简单的递归上练习,而且我仍然坚持写这个是多么精确。尽我所能,我需要一个在for循环中调用自身的函数。这有意义吗?同样结构化的功能的方向也将受到高度赞赏。
答案 0 :(得分:2)
您可以使用itertools.product
和itertools.accumulate
来实现所需的功能:
import itertools
def f(l, d):
for sub in itertools.product(range(1, d+1), repeat=l-1):
yield tuple(itertools.accumulate((1,) + sub))
for l in f(4, 2):
print(l)
(1, 2, 3, 4)
(1, 2, 3, 5)
(1, 2, 4, 5)
(1, 2, 4, 6)
(1, 3, 4, 5)
(1, 3, 4, 6)
(1, 3, 5, 6)
(1, 3, 5, 7)
答案 1 :(得分:0)
这是一个快速而肮脏的实现
def gen_seq(D, L):
for uple in itertools.product(range(1, D+1), repeat=L-1):
yield tuple(numpy.cumsum((1,) + uple))
答案 2 :(得分:0)
递归的关键不仅在于以递归的方式形式化代码,而且还以递归的方式定位你的思想。仔细比较长度3和长度4的结果与距离2。
一个。长度3
1 2 3
1 2 4
1 3 4
1 3 5
湾长度4
1 2 3 | 4
1 2 3 | 5
1 2 4 | 5
1 2 4 | 6
1 3 4 | 5
1 3 4 | 6
1 3 5 | 6
1 3 5 | 7
在长度为4的结果中,|的右侧只是长度为3的结果。这意味着N长度的结果可以从N-1长度导出。
假设我们已经有一个解决k-1长度solve_part(k-1)
的过程,通过将k-1的结果扩展到下一个长度k next_len(solve_part(k-1) ...)
,这个问题自然会以递归的方式解决。
import itertools
def flatmap(func, *iterable):
return itertools.chain.from_iterable(map(func, *iterable))
def next_distance(eachlist, D):
return map(lambda eachdis: eachlist + [eachlist[-1] + eachdis], range(1,D+1))
def next_len(L,D):
return flatmap(lambda eachlist: next_distance(eachlist, D), L)
def solve_it(leng,dis):
def solve_part(k):
if k == 0:
return [[]]
elif k == 1:
return [[1]]
else:
return next_len(solve_part(k-1),dis)
return solve_part(leng)
result=solve_it(4,2)
print([[i for i in j] for j in result])