Заменить элемент во вложенных списках произвольной глубины - PullRequest
0 голосов
/ 17 апреля 2020

Я делаю «самую симпатичную скобку для домашних животных» для своей компании, находясь на карантине, и меня смущает то, как обновлять конкурентов в последующих раундах после одного раунда (кто-то выигрывает).

Скажите, что я победитель - 3, а раунд после:

[[3, 14], [6, 11]]

и раунд после:

[[2, [7, 10]], [[3, 14], [6, 11]]]

Я хочу заменить дочерние узлы на победителя в них, чтобы отразить тот факт, что теперь остается только победитель:

[[3, 14], [6, 11]] -> [3, [6, 11]]

[[2, [7, 10]], [[ 3, 14], [6, 11]]] -> [[2, [7, 10]], [3, [6, 11]]]

Я придумал какой-то код, но он не работает должным образом

[[3, 14], [6, 11]] -> [[3], [6, 11]] (близко, но без сигары)

[[2, [7, 10]], [[3, 14], [6, 11]]] -> [[2, [7, 10]], [[3, 14], [6, 11]]] (без изменений)

    def traverse(traversed_element_of_list_of_lists, winner):
        rebuild = []
        if isinstance(traversed_element_of_list_of_lists, list):
            for value in traversed_element_of_list_of_lists:
                if isinstance(value, int):
                    continue#rebuild.append(value)
                if winner in value:
                    rebuild.append([winner])
                else:
                    rebuild.append(value)
                traverse(value, winner)
        return rebuild

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

Спасибо за помощь!

1 Ответ

1 голос
/ 17 апреля 2020

Ваша рекурсия имеет 3 случая:

  1. Базовый случай, в котором вложенный объект на самом деле не является вложенным, это просто число. Возвратите это напрямую.
  2. Особый случай, когда победитель находится в списке, и в этом случае вы просто хотите вернуть один победитель.
  3. Рекурсивный случай, в котором вы возвращаете новый список путем рекурсивного обхода каждого элемента.

Соберите его вместе как рекурсивную функцию:

def traverse(nested, winner):
    if not isinstance(nested, list):
        return nested

    if winner in nested:
        return winner

    return [traverse(o, winner) for o in nested]

Это даст желаемый результат на ваших примерах.

traverse([[3, 14], [6, 11]], 3)                                                                                                                                                                                                     
# [3, [6, 11]]

traverse([[2, [7, 10]], [[3, 14], [6, 11]]], 3)                                                                                                                                                                                     
# [[2, [7, 10]], [3, [6, 11]]]
...