Понимание Python — Переменная, Определенная Вне Функции, Но Измененная Внутри Функции без возврата

#python #function #recursion #quicksort

Вопрос:

Недавно я наткнулся на алгоритм быстрой сортировки и нашел его пример на Python на Geeksforgeeks здесь: https://www.geeksforgeeks.org/python-program-for-quicksort/

Мой вопрос заключается в следующем: переменная arr определяется вне функции Quicksort.. итак, как переменная известна как в функции, так и вне ее без глобального или возвращаемого значения?

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

 def Partition(arr, low, high):
    i= low - 1
    pivot= arr[high]
    
    for j in range(low, high):
        
        if arr[j] <= pivot:
            i  = 1
            arr[i], arr[j] = arr[j], arr[i]
            
    arr[i 1], arr[high] = arr[high], arr[i 1]
    return i 1



def QuickSort(arr, low, high):
    
    if len(arr) == 1:
        return arr
    
    if low < high:
        
        pi= Partition(arr, low, high)
        
        QuickSort(arr, low, pi-1)
        QuickSort(arr, pi 1, high)
            
            
            
arr = [10, 7, 8, 9, 1, 5]
n= len(arr)
QuickSort(arr, 0, n-1)
print("Sorted array is:")
for i in range(n):
    print("%d" % arr[i])
 

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

1. Прочитайте следующее: nedbatchelder.com/text/names.html

2. Своими словами, как вы думаете, что делает строка кода QuickSort(arr, 0, n-1) внизу? В частности, как вы думаете, каков эффект от того arr , что первое, что находится в скобках?

3. Ага, в этом есть смысл! Это трудно объяснить в этих маленьких абзацах. Так что спасибо вам, ребята. «arr» присваивается объекту списка. Поскольку он является изменяемым, установка другой переменной в значение «arr» привязывает их к одному и тому же объекту, и этот же объект изменяется независимо от того, какое имя используется. Допустим, у меня есть подруга Арианна. Я называю ее «Арр» для краткости. Она ненадолго уезжает, и ее новые друзья тоже называют ее «Арр». Она, личность, — это та, кто меняется и растет с течением времени. Мы теряем связь, и я не знаю, что ее друзья тоже называют ее «Арр». Она возвращается, становится другим человеком, но все еще зовется «Арр».

4. Надеюсь, эта история с «Arr» пройдет хорошо!

Ответ №1:

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

 def Partition(mylst, low, high):
    i= low - 1
    pivot= mylst[high]
    
    for j in range(low, high):
        
        if mylst[j] <= pivot:
            i  = 1
            mylst[i], mylst[j] = mylst[j], mylst[i]
            
    mylst[i 1], mylst[high] = mylst[high], mylst[i 1]
    return i 1



def QuickSort(mylst, low, high):
    
    if len(mylst) == 1:
        return mylst
    
    if low < high:
        
        pi= Partition(mylst, low, high)
        
        QuickSort(mylst, low, pi-1)
        QuickSort(mylst, pi 1, high)
            
            
            
arr = [10, 7, 8, 9, 1, 5]
n= len(arr)
QuickSort(arr, 0, n-1)
print("Sorted array is:")
for i in range(n):
    print("%d" % arr[i])
 

Даже помимо этого, пока вы не меняете, что такое переменная, вы все равно можете изменять глобальные значения в Python. Различие здесь в том , что вы изменяете не значение arr , а значение фактического массива, на который он указывает, поэтому, даже если бы вы хотели изменить глобальный массив, вам не понадобилось бы ключевое слово global.

Подобные вещи обычно не часто делаются на практике, так что не беспокойтесь об этом слишком сильно. По крайней мере, в этом сценарии массив передается в функцию, и функция быстрой сортировки напрямую изменяет массив, который передается в нее (и так получилось arr в этом примере).

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

1. Итак, в вашем примере, в инструкции print в конце, будет ли это также печатать измененное значение из исходного определенного массива? Мы в основном говорим об указателях? Может быть, мне просто нужно почитать больше самостоятельно. Это казалось странной проблемой, поэтому я подумал, что, по крайней мере, это может помочь кому-то еще опубликовать этот вопрос. Спасибо за быстрый и подробный ответ!

2. Переменные @Shane — это ссылки на объекты. Python совсем не похож на C, если вы исходите из этого фона. Вы можете думать об этом так, как будто все является указателем, который автоматически разыменовывается для вас, но в python нет указателей как части языка как такового.