Почему моя функция python возвращает несколько скобок? - PullRequest
0 голосов
/ 15 ноября 2011

Я в некоторой степени новичок в python, но я пытаюсь создать рекурсивную функцию, которая работает так же, как встроенная функция range:

def Range (lo, hi):
    if lo >= hi:
        return []
    else:
        return [lo, Range (lo+1,hi)]

но возвращает несколько списков.

Вместо [3,4,5,6], что я и хочу, его возвращение [3,[4,[5,[6,[]]]]] Почему это так и как мне это исправить?

Ответы [ 4 ]

5 голосов
/ 15 ноября 2011

Когда вы повторяете это, Range возвращает список каждый раз:

Range(3,7)
# translates to
[3, Range(4,7)]
# which translates to
[3, [4, Range(5,7)]]
# etc.

Чтобы избежать этого, сложите свои списки вместе:

def Range (lo, hi):
    if lo >= hi:
        return []
    else:
        return [lo] + Range(lo+1, hi)

EDIT:

Как указывает @delnan, эта функция очень неэффективна - она ​​рекурсивно используется в языке без оптимизации хвостового вызова * и генерирует два ( возможно три ) новых списков для каждого уровня рекурсии. Ответ @ mipadi более производительный, поскольку он создает только один список (аргумент acc или accumulator) и передает его по мере повторения.

* Это может не быть правдой для языка Python, но я на 99% уверен, что это верно для наиболее распространенной реализации Python, а именно CPython.

3 голосов
/ 15 ноября 2011

Ваша функция Range возвращает список, поэтому в последней строке вы возвращаете список в списке.Что вы, вероятно, должны сделать, это сохранить аккумулятор и добавить значения к этому:

def Range(lo, hi, acc=None):
    if acc is None:
        acc = []
    if lo >= hi:
        return acc
    else:
        acc.append(lo)
        return Range(lo+1, hi, acc)
1 голос
/ 15 ноября 2011
def Range (lo, hi):
    if lo >= hi:
        return []
    else:
        return [lo] + Range (lo+1, hi)

но вы можете получить StackOverflow

0 голосов
/ 15 ноября 2011

Каждая рекурсия в Range возвращает список, который является вторым элементом в списке для предыдущей рекурсии.Конечно, Python имеет встроенную функцию для этого , но если вы хотите собрать его самостоятельно, вы, вероятно, просто хотите закончить с

return [lo] + Range(lo+1, hi)
...