TypeError при назначении среза: "можно назначить только итерацию" - PullRequest
1 голос
/ 19 июня 2020

Я пишу рекурсивный код, чтобы перевернуть список на месте. Это то, что у меня есть, но код не может назначить фрагмент входному списку, что дает ошибку 'NoneType' object is not iterable:

def reverse(a):
    if len(a) == 1:
        return

    temp = a[0]
    a[0] = a[-1]
    a[-1] = temp
    a[1:-1] = reverse(a[1:-1])
    return a

Я прочитал, что фрагменты не являются объектами, поэтому я попытался использовать list() и range() для преобразования возвращенного фрагмента, но при этом я все равно получаю ту же ошибку. Есть ли способ назначить кусок другому фрагменту массива?

Ответы [ 3 ]

1 голос
/ 19 июня 2020

Реверс на месте

Мы просто будем менять местами начало и конец списка, пока они оба не встретятся

def reverse(a,start=0,end=len(a)-1):
    if start==end:return
    a[start],a[end] = a[end],a[start]
    reverse(a,start+1,end-1)
    # return a # if it is inplace no need to return
a = [1,2,3,4,5]
reverse(a)
print(a)
[5, 4, 3, 2, 1]
1 голос
/ 19 июня 2020

Вся ваша проблема - return, который отправляет None и дает 'NoneType' object is not iterable

Вам нужно return a. И остальной код начинает работать.

BTW: Вы также можете использовать <= 1 вместо == 1 для работы с пустым списком.

def reverse(a):
    if len(a) <= 1: # <-- `<=` to work with empty list
        return a    # <-- has to return `a`

    temp = a[0]
    a[0] = a[-1]
    a[-1] = temp
    #a[0], a[-1] = a[-1], a[0]

    a[1:-1] = reverse(a[1:-1])

    return a

# --- tests ---

print(reverse([1,2,3,4,5]))
print(reverse([1]))
print(reverse([]))

EDIT: Для замены элементов вы также можете использовать

a[0], a[-1] = a[-1], a[0]

EDIT: Использование фрагмента для создания списка с одним элементом и list + list для присоединения списки, которые вы можете сделать:

def reverse(a):
    if len(a) <= 1:
        return a

    return a[-1:] + reverse(a[1:-1]) + a[:1]

EDIT: Вы даже можете записать это как lambda функцию (если вам нравится функциональное программирование , которое часто использует рекурсия)

reverse = lambda a: a if len(a) <= 1 else a[-1:] + reverse(a[1:-1]) + a[:1]

# --- tests ---

print(reverse([1,2,3,4,5]))
print(reverse([1,2,3,4]))
print(reverse([1]))
print(reverse([]))
0 голосов
/ 19 июня 2020

Думаю, этот алгоритм будет немного ближе к тому, что вы имеете в виду:

  • Здесь мы передаем индекс функции, которую вы уже создали.
  • Затем мы увеличили бы этот индекс, используя (-~index или просто index + 1).
def reverse(a, index=0):
    if len(a) == 0:
        return []
    if len(a) == 1:
        return a
    if index == len(a) - 1:
        return a

    temp = a[0]
    a[0] = a[-1]
    a[-1] = temp
    return reverse(a, index + 1)


print(reverse([1, 2, 3, 5, 6, 7, 8, 9]))
print(reverse([100, 90, -10, 1200, 1, 2, 3, 5, 6, 7, 8, 9]))



Три оператора, которые уже есть в вашем коде: гораздо больше «алгоритмов c» (на всех языках), чем при использовании Python подкачки (a, b = b, a):

temp = a[0]
a[0] = a[-1]
a[-1] = temp

Вывод

[9, 2, 3, 5, 6, 7, 8, 1]
[9, 90, -10, 1200, 1, 2, 3, 5, 6, 7, 8, 100]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...