2015-11-18 2 views
4

Есть простым способ преобразованияПреобразовать из кортежа кортежей вложенных кортежей в Python

t = ((1,), (1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)) 

следующей рекурсивную структуру, где каждый следующий кортеж добавленная в качестве элемента предшествующего кортежа

(1, (1, 2, (1, 2, 3, (1, 2, 3, 4, (1, 2, 3, 4, 5))))) 

Каков предел для этого гнездования? Могу ли я иметь 1000 или 10000 таких вложенных кортежей?

ОБНОВЛЕНИЕ: Кажется, что t вложенность неограничена (проверено с 10000 после установки предела рекурсии до 100).

В окне 7, Python 3.5) предел рекурсии составляет около 300, но может быть поднят как (reference). Это не связано со структурой t, но может быть связано с подпрограммой Python, доступ к вложенным уровням результирующей структуры.

sys.getrecursionlimit() # display current recursion level 
sys.setrecursionlimit(10000) # set recursion level to 1000 
+1

предел рекурсии вы упомянули связан с рамками Nember стеки мы можем использовать, то есть речь идет о том, как глубоко рекурсивные вызовы функций могут идти. Это совершенно не связано с тем, насколько глубоко вы можете вставлять кортежи, подобные этому, и я ожидаю, что он неограничен (за исключением доступной памяти). – wim

+0

Замечательная заметка! Я обновил вопрос. Однако я сталкиваюсь с проблемой ограничения рекурсии, когда я запускаю код Дэвида и отображаю «результат». Смотрите мой комментарий к Дэвиду. –

ответ

0

Вы могли бы сделать

def convert(t): 
    result = t[-1] 
    for x in t[-2::-1]: 
     result = x + (result,) 
    return result 

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

+0

Мне нравится ваш подход, потому что его краткое и не использует ненужные инструменты. Благодаря! –

+0

Дэвид, аккуратная рутина. Он может извлечь выгоду из предела рекурсии настройки до глубины 't', иначе он выдает« RecursionError: максимальная глубина рекурсии, превышаемая при вызове объекта Python »для глубоко вложенного' t'. Попробуйте 'sys.setrecursionlimit (10)', за которым следует convert (tuple (tuple (range (k)) для k в диапазоне (1,20))) ' –

+1

@EmilyHill В моем коде нет рекурсии. Конкретная ошибка: «RuntimeError: максимальная глубина рекурсии превышена при получении отпечатка кортежа», который является попыткой Python REPL и не может распечатать результат, как я и предсказывал. Если вы измените введенную команду, чтобы отбросить вывод, добавив '[: 0]' (чтобы взять пустой фрагмент), все будет хорошо. –

0

Для вложенной конструкции:

def f(t): 
    res = t[-1] 
    for x in t[-2::-1]: 
     res = x + (res,) 
    return res 

t = ((1,), (1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)) 
print f(t) 

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

6

Использование functools.reduce:

>>> from functools import reduce 
>>> t = ((1,), (1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)) 
>>> reduce(lambda a, b: b + (a,), reversed(t),()) 
(1, (1, 2, (1, 2, 3, (1, 2, 3, 4, (1, 2, 3, 4, 5))))) 
+2

Я ждал ответа на сокращение. Одно из немногих случаев, когда фактическое сокращение действительно *. – wim

+0

Отличное решение. Благодаря! –

+1

@EmilyHill, FYI, ответ accept не будет работать с пустым кортежем. – falsetru

Смежные вопросы