2015-10-15 3 views
0

Я хочу взять вложенный списокКак мне изменить каждое значение вложенного вложенного списка рекурсивно и вернуть другой похожий список?

[[[1,2],[4,5]], 1, [1,3,4],[2,3,4]] 

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

[[[2,3],[5,6]], 2, [2,4,5],[3,4,5]] 

Я сделал некоторый прогресс, делая это с делать рекурсивную функцию, где я проверить, если это список или элемент для изменения. Я в тупике, когда дело доходит до того, как скомпилировать список еще раз. Разве нет простого способа сделать это? Следующий код - это то, что у меня есть.

def add1(nodelist): 
    list_of_lists = [] 
    name_nodes.nodes = [] 
    def recurse_list(nodelist): 
     name_nodes.nodes = [] 
     edit_list = False 
     for r in nodelist: 
      if type(r) == list: 
       recurse_list(r) 
      else: 
       edit_list = True 
       name_nodes.nodes.append(r+1) 
     if edit_list == True: 
      list_of_lists.append(name_nodes.nodes) 
    recurse_list(nodelist) 
    return list_of_lists 

Этот код заставляет меня следующий вывод

[[2, 3], [5, 6, 2], [2, 4, 5], [3, 4, 5], [3, 4, 5]] 

Я удивлен, что это не какой-то модуль или некоторые встроенные функциональные возможности, чтобы лучше обрабатывать вложенные списки, потому что есть очень много вопросов обработки подобное, но другое поведение , Самый близкий вопрос, который я мог найти, - here. Но у меня просто не было того, что я искал. Спасибо за любые ответы.

+0

«если это список или элемент [sic] для изменения» - это не всегда можно сделать в Python на 100% -ном уровне. –

ответ

2
def add1(L): 
    for i, elem in enumerate(L): 
     if isinstance(elem, int): 
      L[i] += 1 
     else: 
      L[i] = add1(elem) 
    return L 

Выход:

>>> L = [[[1,2],[4,5]], 1, [1,3,4],[2,3,4]] 
>>> add1(L) 
[[[2, 3], [5, 6]], 2, [2, 4, 5], [3, 4, 5]] 
+0

Это так прекрасно, что я буду плакать. Я сделал несколько изменений. Я изменил 'L [i] + = 1' на' L [i] = func (elem) 'и изменил' isinstance (elem, int) 'to' not isinstance (elem, list) 'добавленный func в списке аргументов и переименовал его в nmap. Теперь я могу легко изменить вложенный список. Спасибо огромное! – raz

0

На самом деле, я думал об этом в последнее время. Вот часть кода, который я написал для этого, выдержки из какой-то демонстрации. Функция nmap() работает как встроенная функция map(), но она работает с вложенными списками.

import functools 


def mapper_nester(function): 
    @functools.wraps(function) 
    def wrapper(*point): 
     try: 
      res = function(*point) 
     except TypeError: 
      res = map(mapper_nester(function), *point) 
     return res 
    return wrapper 


def nmap(function, *seq): 
    """nmap(funtion, seq[, seq ...]) -> nested list of similar structure.""" 
    return map(mapper_nester(function), *seq) 

>>> nested_list = [0, [1], [[[[2]]]], 
        [3, [], [4, 5]], 
        [6, [7, 8], 
        9, [[[]], 10, []]], 11, 
        [], [], [12]] 
>>> nmap(lambda x: x + 1, nested_list) 
[1, 
[2], 
[[[[3]]]], 
[4, [], [5, 6]], 
[7, [8, 9], 10, [[[]], 11, []]], 
12, 
[], 
[], 
[13]] 

Это рекурсивная функция, которая пересекает вложенную (рекурсивную) структуру.

Плюсы:

Минусы:

  • Он подвергается пределу рекурсии, так что не очень полезно для глубоко вложенных списков.
  • В контексте Python рекурсивные функции в целом не одобряются.
  • Эта функция использует TypeError для проверки «типа» (атома или набора атомов) узла, но это не всегда надежно (и зависит от того, что на самом деле выполняет отображаемая функция), особенно при наборе текста утилит Python.

На самом деле я написал намного больше кода, чтобы ответить на последний вопрос, но здесь довольно громоздко.[1]

[1] Что он делает, это создать временную ограниченную «типизированную вселенную», которая четко отличает атомы от коллекций атомов (это делается уродливо, используя isinstance() и друзей, а также создание этой «типизированной вселенной» можно настроить), а затем поднять как данные, так и отображаемую функцию в этот юниверс, где поднятая функция может действовать только на атомы и производить атомы как ценность. Вложенная карта выполняется в этом юниверсе, и тогда результат затем можно понизить до обычного юнита Python.

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