Почему элемент массива не меняет положение?

#python

Вопрос:

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

 def sort(list):

    n = len(list)
    for outer_iteration in range(1, n):
        for inner_iteration in range(1, n):
            number1 = list[inner_iteration - 1]
            number2 = list[inner_iteration]
            if number1 > number2:
                list[inner_iteration - 1] , list[inner_iteration] = list[inner_iteration] , list[inner_iteration - 1]


list = [10,47,1,0,-39,-5]
sort(list)
print(list)
 

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

 def sort(list):

    n = len(list)
    for outer_iteration in range(1, n):
        for inner_iteration in range(1, n):
            number1 = list[inner_iteration - 1]
            number2 = list[inner_iteration]
            if number1 > number2:
                number1 , number2 = number2, number1

list= [10,47,1,0,-39,-5]
sort(list)
print(list)
 

Я проверил PythonTutor, и мне кажется, что во 2-м блоке кода номера, присвоенные number1 и number 2 действительно меняются местами, но только в переменных, а не в списке.
Я использовал кортежи в обоих случаях для обмена и с тех пор number1 , как и number2 были назначены list[inner_iteration - 1] и list[inner_iteration] , почему второй случай ведет себя иначе, чем первый?

Комментарии:

1. number1, number2 = number2, number1 только переназначает имена number1 и number2 . Базовые ценности, которые они должны представлять, отбрасываются, когда их заставляют указывать на что-то другое

2. В Python мы называем эти списки .

3. В любом случае, пожалуйста, прочтите nedbatchelder.com/text/names1.html .

4. Связанные: сравните две функции def f(l): l = l [3] и def g(l): l = [3] . Похоже, они делают то же самое, но это не так. Попробуйте их и попытайтесь понять разницу!

5. @KarlKnechtel Правильно ли говорить, что, поскольку я вносил изменения (менял местами) в целые числа, которые являются неизменяемыми, следовательно, изменения, внесенные в number1 и number2 , не видны на list[inner_iteration-1] и list[inner_iteration] ? Следовательно, список не был обновлен?

Ответ №1:

Таким образом, во втором фрагменте кода вы просто меняете переменные number1 и number2 на какое-то новое значение (в вашем случае вы просто меняете значения). Но эти значения не являются ссылками на числа в массиве в этих позициях, что означает, что изменение не отражается в массиве. Чтобы обновить значения в массиве, вам необходимо повторно назначить числа обратно в массив после изменения переменных.

 def sort(array):

    n = len(array)
    for outer_iteration in range(1, n):
        for inner_iteration in range(1, n):
            number1 = array[inner_iteration - 1]
            number2 = array[inner_iteration]
            if number1 > number2:
                number1 , number2 = number2, number1
            array[inner_iteration - 1] = number1
            array[inner_iteration] = number2

array = [10,47,1,0,-39,-5]
sort(array)
print(array)
 

Приведенный выше исправленный код поможет вам понять рассуждения.

Ответ №2:

Взгляните на простой пример:

 a = 5
b = a
b = 3
print(a) # prints 5
 

В этом случае b = a не означает b , что всегда равно a . Если вы переназначите b новое значение раньше, a оно сохранит свое первое значение.