Рекурсия и мутация списка - PullRequest
0 голосов
/ 10 февраля 2020

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

def expand_strings(L,s,i):
    if len(L) == 0:
        return
    else:
        if len(L[0]) - 1 <= i:
            L[0] += s
        elif len(L[0]) - 1 > i:
            new_string = L[0][:i] + s + L[0][i:]
            L[0] = new_string
            expand_strings(L[1:], s, i)
            return

L: список ввода, содержащий возможные 1 или более строк s: дополнительная часть строки, которую мне нужно «вставить» или «добавить» к строковым элементам в списке i: индекс строки, в которую я хочу вставить или добавить s.

Основной целью этой функции является следующее:

1. if the index i within the range 0 ~ len(string_element_in_list), then I insert my s starting from index i


2. if the index i is larger than what the current string length, then I do the append s.

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

Спасибо за помощь заранее. :)

1 Ответ

3 голосов
/ 10 февраля 2020

Проблема в рекурсивном вызове expand_strings(L[1:], s, i). Когда вы используете нарезку для получения части вашего списка, python создает новую копию этого подсписка. Таким образом, рекурсивный вызов создает копию вашего списка, за исключением первого элемента, и работает с этой копией.

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

def expand_strings(L,s,i):
    if len(L) == 0:
        return []
    else:
        if len(L[0]) - 1 <= i:
            L[0] += s
        elif len(L[0]) - 1 > i:
            new_string = L[0][:i] + s + L[0][i:]
            L[0] = new_string
        return [L[0]] + expand_strings(L[1:], s, i)

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

def expand_strings(L,s,i,start):
    if start == len(L):
        return
    if len(L[start]) - 1 <= i:
        L[start] += s
    else:
        L[start] = L[start][:i] + s + L[start][i:]
    expand_strings(L, s, i, start + 1)
...