2015-03-23 2 views
0

Мне нужно определить функцию rec_range (n), которая принимает натуральное число и возвращает TUPLE чисел до числа n.Python Recursion: Range

т.е. rec_range возвращает (5) возвращает (0,1,2,3,4) rec_range (1) (0,)

Это то, что я придумал до сих пор.

def rec_range(n): 
    """takes a natural number n and returns a tuple of numbers starting with 0  and ending before n 

    Natural Number -> Tuple of Numbers""" 
    if n == 0: 
     return 0 
    else: 
     return (rec_range(n-1),) 

Это работает для rec_range (1).

*** Ограничения: должны быть определены рекурсивно, не может использовать списки, петли или использовать функцию существующий диапазон()

+2

После того, как вы это сделаете, попробуйте 'rec_range (1500)', и вы обнаружите, почему рекурсия не является магическим решением для всех проблем ;-) – Kevin

+0

@Kevin: Это просто представляет проблему с незнакомыми языками оптимизация хвостового вызова и ограничение того, насколько велик объем их стека. – ArtOfWarfare

+0

@ArtOfWarfare эта рекурсия не является даже хвостовой рекурсией ... – HuStmpHrrr

ответ

4

Я хотел бы написать это следующим образом:

def rec_range(n): 
    if n < 1: 
     return() 
    else: 
     return rec_range(n - 1) + (n - 1,) 

print(rec_range(4)) # prints (0, 1, 2, 3) 

Это также может обрабатывать отрицательные аргументы.

+0

Это было именно то, что я искал :) Спасибо – Trumpetplayer0098

+0

@ Trumpetplayer0098: в этом случае вы должны принять этот ответ! –

1

Это красиво и краткое, я думаю:

def rec_range(n): 
    if not n <= 1: return rec_range(n-1) + (n-1,) 
    return (0,) 

В основном вы рекурсию вниз, пока не достигнешь 1, и для каждой рекурсии добавить один меньше, чем число, которое вы только Рекурсию на позиции мудрой вашего кортежа.

Выходы:

>>>rec_range(4) 
(0, 1, 2, 3) 
+0

'rec_range (0)' => BOOM – ArtOfWarfare

+0

@ArtOfWarfare: P, но он указывает, что эта функция должна потреблять натуральное число. – miradulo

+0

Эх, тривиально модифицировать программу, чтобы не взорваться с неестественными числами (просто измените 'n == 1' на' n <= 1'), чтобы я это сделал. Использование вашего решения сбой с любым поплавком или любым значением в 1. Это одно изменение фиксирует оба из них. – ArtOfWarfare

0

Просто держать конкатенации кортежей для числа, один меньше, пока не будет достигнуто:

rec_range = lambda n: rec_range(n - 1) + (n - 1,) if n > 0 else() 
+0

Зачем передавать списки в 'tuple()' вместо того, чтобы просто использовать кортежи? 'tuple ([n - 1])' такой же, как '(n-1,)'. – ArtOfWarfare

+0

Назначение лямбда считается [плохой стиль] (https://www.python.org/dev/peps/pep-0008/#programming-recommendations) – mata

+0

@mata: ОП просит неэффективного, сломанного (для n> 1000 или около того), повторное выполнение того, что уже доступно как встроенный. Я думаю, что незначительное нарушение PEP8 довольно незначительно по сравнению. :-) –

-1

Как насчет однострочника:

def rec_range(n): 
    return rec_range(n-1) + (n-1,) if n > 0 else() 

Или с лямбдами:

rec_range = lambda n: rec_range(n-1) + (n-1,) if n > 0 else() 
+0

Сдвиг без объяснения причин. Как грубо. – ArtOfWarfare

+0

Да, диапазон должен быть эксклюзивным. Это все. –

+0

Также попробуйте вернуть пустой кортеж для плохих входных значений. Таким образом, когда итерация блока кода не будет выполняться так же, как если бы вы использовали традиционный диапазон. –