递归任意序列

时间:2018-03-31 16:13:41

标签: python recursion

我正在尝试定义递归几何函数,该函数将询问用户序列的第一个值和序列的乘数值。该函数应该给出一个所需长度的序列作为参数,并产生该长度的任意几何序列的列表作为返回值。作为一个澄清示例,如果用户提供5作为起始值而3作为具有所需长度6的乘数,则任意几何序列的前6个元素将是[5,15,45,135,405,1215]

当我运行此代码时,我以奇怪的随机顺序获取序列。到目前为止,这是我的代码:

# This will define a recursive arbitrary Geometric sequence function
def recursive_geo_helper(length):
    start = int(input("Enter the first value of the sequence: "))
    multiplier = int(input("Enter the value that must be multiplied: "))
    return actual_recursive_geo(length, start, multiplier)


def actual_recursive_geo(length, start, multiplier):
    sequence = []

   # print(start)
    if length <= 1:

        exit()
       # return sequence

    else:
        sequence.append(start)

        start = start * multiplier
        length = length - 1



        return actual_recursive_geo(length, start, multiplier)

#recursive_geo_helper(5)

print(recursive_geo_helper(6))

2 个答案:

答案 0 :(得分:3)

遗憾的是,您的代码没有多大意义。以下是它的一些问题:内置exit永远不应该在shell之外使用,你的函数不会返回基本情况,即使它没有,它也不会递归地附加到那个基本情况。

解决所有这些问题,这就是你的递归解决方案。

def actual_recursive_geo(length, a, r):
    if length <= 0:
        return  [] # base case
    else:
        return [a] + actual_recursive_geo(length - 1, a * r, r) # prepend to your base case

虽然这样做效率有点低,因为它会进行大量不必要的列表连接..

发电机

让我建议从头开始使用更合适的数据结构来表示无限序列:生成器。

发生器可以懒惰地表示无限序列。此外,Python为您提供了itertools标准库来操作它们。在这里,我们将返回一个生成器,并使用itertools.islice对其进行切片。

import itertools

def geometric_input():
    """
    Prompt the user for an initial value and a ratio
    Return the corresponding geometric series
    """
    a = int(input("Enter the first value of the sequence: "))
    r = int(input("Enter the ratio: "))
    return geometric_sequence(a, r)


def geometric_sequence(a, r):
    """ Return a generator for the sequence x_i = a * r ^ i"""
    r_exp = 1
    while True:
        yield a * r_exp
        r_exp *= r


seq = geometric_input()

first_elements = list(itertools.islice(seq, 6))

print(*first_elements)

这是输出。

Enter the first value of the sequence: 5
Enter the ratio: 3
5 15 45 135 405 1215

关于生成器的另一个好处是元素在生成时被消耗。这意味着如果再次对生成器进行切片,您将获得序列中的下一个元素

next_elements = list(itertools.islice(seq, 6))

print(*next_elements)
# prints: 3645, 10935, 32805, 98415, 295245, 885735

答案 1 :(得分:0)

我相信你的问题是你在声明函数中的序列并且没有正确地返回它。

此外,如果我们要使用递归,我们可以更进一步,避免通过将修改后的变量传递给递归调用来改变我们的变量。

def geo(sequence, length, multiplier):
    if length <= 1:
        return sequence
    else:
        return sequence + geo([sequence[-1] * multiplier], length - 1, multiplier)

以下是REPL的输出:

>>> geo([5], 6, 3)
[5, 15, 45, 135, 405, 1215]

P.S。我更像是一个JavaScript而不是Python人,所以我首先在JS中完成它然后移植它。

这是JavaScript中的等效函数:

function geo(sequence, length, multiplier) {
    if (length <= 1) {
      return sequence
    }
    return sequence.concat(geo([sequence.slice(-1) * multiplier], length - 1, multiplier))
}
console.log(geo([5], 6, 3))