Как сделать вставку в список переменных размеров? - PullRequest
0 голосов
/ 18 сентября 2018

Я пытаюсь создать метод (или несколько методов, которые вызываются одним), который может вставить вложенный список в любой форме, которую я выберу.Я использую рекурсивный метод, которому присваиваются индексы, в которые следует добавить элемент в виде списка.Он постепенно сужает вставку, переходя к указанному элементу при каждом вызове и повторяя этот элемент до тех пор, пока у него больше индексов.Как только он сузился до одномерного списка, он вставляет элемент после элемента по заданной им координате, а затем возвращает этот список.

Вот код, который у меня сейчас есть:

def layered_appension(self, lst, coordinates, to_add):
    print('List:' + str(lst) + '\nCoordinates: ' + str(coordinates))
    if len(coordinates) > 1:
        insertion = self.layered_appension(lst[coordinates[0]], coordinates[1:], to_add)
    else:
        insertion = to_add
    out_list = self.insert(lst[coordinates[0]], coordinates[0], insertion)
    return out_list

def insert(self, lst, location, insertion):
    out_list = lst[:location]
    out_list.append(insertion)
    for element in lst[location + 1:]:
        out_list.append(element)
    return out_list

Если бы он работал правильно, то вызов

self.layered_appension([[2, 5, 1], 1, [3, [7, 2]]], [2, 1, 1], 9))

возвратил бы [[2, 5, 1], 1, [3, [7, 2, 9]]].Тем не менее я получаю сообщение об ошибке: «TypeError: объект« int »не является подписным».Что я здесь не так делаю?

Редактировать: В итоге я много переработал свой код и упростил его.Вот новый метод, который работает:

def layered_appension(self, lst, coordinates, to_add):
    print('List:' + str(lst) + '\nCoordinates: ' + str(coordinates))
    if len(coordinates) > 1:
        into_lst = lst.pop(coordinates[0])
        lst.insert(coordinates[0], self.layered_appension(into_lst, coordinates[1:], to_add))
    else:
        lst.insert(coordinates[0], to_add)
    return lst

Спасибо за совет!это очень помогло.

1 Ответ

0 голосов
/ 18 сентября 2018

ДИАГНОЗ

Добавьте еще один print вверху insert, чтобы сделать проблему мучительно очевидной:

def insert(lst, location, insertion):
    print('Insert', lst, location, insertion)
    out_list = lst[:location]
    ...

Выход:

List:[[2, 5, 1], 1, [3, [7, 2]]]
Coordinates: [2, 1, 1]
List:[3, [7, 2]]
Coordinates: [1, 1]
List:[7, 2]
Coordinates: [1]
Insert 2 1 9
Traceback (most recent call last):
  File "so.py", line 18, in <module>
    print(layered_appension([[2, 5, 1], 1, [3, [7, 2]]], [2, 1, 1], 9))
  File "so.py", line 4, in layered_appension
    insertion = layered_appension(lst[coordinates[0]], coordinates[1:], to_add)
  File "so.py", line 4, in layered_appension
    insertion = layered_appension(lst[coordinates[0]], coordinates[1:], to_add)
  File "so.py", line 7, in layered_appension
    out_list = insert(lst[coordinates[0]], coordinates[0], insertion)
  File "so.py", line 12, in insert
    out_list = lst[:location]
TypeError: 'int' object is not subscriptable

При попытке выполнить вставку здесь:

out_list = insert(lst[coordinates[0]], coordinates[0], insertion)

Вы откопали один уровень слишком далеко. Вместо вставки в список после значения 2 вы пытаетесь вставить в сам 2.

ЧАСТИЧНЫЙ РЕМОНТ

Во-первых, очевидным изменением является передача lst вместо значения до цели вставки. Во-вторых, я позволил себе сменить имя функции, чтобы вы не переназначали полезный встроенный метод. Затем я использовал этот метод insert, чтобы сократить фактическую вставку. Если вы проследите результаты, вы увидите, что deep_insert теперь возвращает ожидаемое значение [7, 2, 9].

У вас есть еще одна проблема: в layered_appension вы продолжаете вызывать собственный метод вставки нижнего уровня вместо замены существующего элемента. Это накапливает различные высокоуровневые копии вставки. Текущая версия, наконец, дает

[[2, 5, 1], 1, [3, [7, 2]], [3, [7, 2], [7, 2, 9]]]

Сделайте замену, а не вставьте неосновные случаи, и все готово.

def layered_appension(lst, coordinates, to_add):
    print('List:' + str(lst) + '\nCoordinates: ' + str(coordinates))
    if len(coordinates) > 1:
        insertion = layered_appension(lst[coordinates[0]], coordinates[1:], to_add)
    else:
        insertion = to_add
    out_list = deep_insert(lst, coordinates[0], insertion)
    return out_list

def deep_insert(lst, location, insertion):
    print('deep_insert', lst, location, insertion)
    out_list = lst[:]
    out_list.insert(location+1, insertion)
    return out_list
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...