«IndexError: список индекса вне диапазона» при обмене элементами в списке - PullRequest
0 голосов
/ 25 октября 2019

Мне нужно написать функцию 'swaplist', которая выполняет следующие действия:

, заданная в списках ввода 2:

list1, list2

, например:

[s4, s6]

[4,2,3,6,5]

* имейте в виду, [s5] не может быть задано на входе

возвращает список, в котором 4 заменяется следующим числом, а 6 заменяется следующим числом

[2,4,3,5,6]

Это код, который я написал:

def swaplist(list1,list2):
    list3=list2
    for i in list3:
        if ('s'+str(i)) in list1:
            a=list3.index(i)
            b=a+1
            list3[a],list3[b]=list3[b],list3[a]
    return list3

Я попытался запустить этот код, и я получил следующую ошибку:

IndexError: list index out of range

Кто-нибудь знает, как это исправить?

Спасибо, ребята, за ваше время

  • и извините за мой ломаный английский

Ответы [ 3 ]

1 голос
/ 25 октября 2019

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

Если мы делаем print(list3) каждый раз, когда меняем число, мы можем видеть, что происходит со списком во время цикла,

После проверки первого числа в списке, мы видим, что это 4, который следует поменять местами. Список был [4, 2, 3, 5, 6] и теперь [2, 4, 3, 5, 6].

Давайте перейдем ко второму числу в списке. Поскольку вы изменили исходный список, второе число теперь равно 4, которое будет заменено следующим номером.

Это то, что программа печатает после каждого обмена:

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

Ваш номерчетверка перемещается на следующее место в списке, после чего проверяется снова.

Способ решить эту проблему - создать новый список, а не изменять исходный список. Как то так:

def swaplist(list1,list2):
    # Make a copy of the original list so we don't modify it.
    # Use a more verbose name for the list so it's clear what the purpose is
    result_list=list2.copy()

    # Use enumerate to get both the index (i), as well as the list item in one go.
    for i, item in enumerate(list2):
        if ('s'+str(item)) in list1:
            # Swap the values using the original list as source.
            result_list[i],result_list[i+1]=list2[i+1],list2[i]
    return result_list
0 голосов
/ 25 октября 2019

Как уже упоминал JohanC, проблема в том, что вы меняете список, по которому вы зацикливаетесь. Вы можете скопировать сначала list2, а затем только изменить list3.

def swaplist(list1,list2):
    list3=list2.copy()
    for i in list2:
        print(i)
        if f's{i}' in list1:
            a=list3.index(i)
            b=a+1
            list3[a],list3[b]=list3[b],list3[a]
    return list3
0 голосов
/ 25 октября 2019

Это похоже на домашнее задание.

Проблема в том, что вы меняете тот же список, что и список, через который вы перебираете. Первым шагом к решению является циклический просмотр списка list2 и внесение изменений в list3. Таким образом, в первый раз, когда вы сталкиваетесь с 4, вы меняете его вправо. Но затем, следующий элемент, который вы встретите в списке 3, снова 4, и вы меняете его снова. Это продолжается до тех пор, пока вы не достигнете конца list3 с ошибкой, пытаясь обменять 4 за пределы конца.

Но затем возникает другая проблема: просто установив list3=list2, вы на самом деле не создаетеновый списокИ list3, и list2 указывают на один и тот же список.

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

def swaplist(list1,list2):
    list3=list2
    for i in list3:
        print("i:", i)
        if ('s'+str(i)) in list1:
            a=list3.index(i)
            b=a+1
            list3[a],list3[b]=list3[b],list3[a]
            print('s' + str(i), a, b, "list is now:", list3)
    return list3

* спойлер * Однако, чтобы действительно решить вашу проблему, вам нужно, чтобы list3 был совершенно новым списком. Для действительно сложных структур вам нужна глубокая копия, и для создания такой deepcopy есть библиотечная функция. Для простого списка можно создать копию, повторив итерацию в вашем списке. Или используйте функцию copy(), как упоминалось другими.

def swaplist(list1,list2):
    list3=[i for i in list2]
    for i in list2: # note we are looping through list2 and changing list3
        print("i:", i)
        if ('s'+str(i)) in list1:
            a=list3.index(i)
            b=a+1
            list3[a],list3[b]=list3[b],list3[a]
            print('s' + str(i), a, b, "list is now:", list3)
    return list3
...