Реализация функции сортировки слиянием в классе Python, ошибки
Итак, у меня есть определенная функция, которая отлично работает при выполнении сортировки слиянием на линейном массиве, если она реализована его одиноким массивом, но если я добавлю ее в класс, это вызовет ошибку. Я думаю, что это отличный пример того, что я не совсем понимаю о том, как работают классы; возможно, в отношении управления пространством имен (?).
Увидеть ниже:
def sort(array):
print('Splitting', array)
if len(array) > 1:
m = len(array)//2
left = array[:m]
right = array[m:]
sort(left)
sort(right)
i = 0
j = 0
k = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
array[k] = left[i]
i += 1
else:
array[k] = right[j]
j += 1
k += 1
while i < len(left):
array[k] = left[i]
i += 1
k += 1
while j < len(right):
array[k] = right[j]
j += 1
k += 1
print('Merging', array)
arr = [1,6,5,2,10,8,7,4,3,9]
sort(arr)
Производит ожидаемый правильный вывод:
Splitting [1, 6, 5, 2, 10, 8, 7, 4, 3, 9]
Splitting [1, 6, 5, 2, 10]
Splitting [1, 6]
Splitting [1]
Merging [1]
Splitting [6]
Merging [6]
Merging [1, 6]
Splitting [5, 2, 10]
Splitting [5]
Merging [5]
Splitting [2, 10]
Splitting [2]
Merging [2]
Splitting [10]
Merging [10]
Merging [2, 10]
Merging [2, 5, 10]
Merging [1, 2, 5, 6, 10]
Splitting [8, 7, 4, 3, 9]
Splitting [8, 7]
Splitting [8]
Merging [8]
Splitting [7]
Merging [7]
Merging [7, 8]
Splitting [4, 3, 9]
Splitting [4]
Merging [4]
Splitting [3, 9]
Splitting [3]
Merging [3]
Splitting [9]
Merging [9]
Merging [3, 9]
Merging [3, 4, 9]
Merging [3, 4, 7, 8, 9]
Merging [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Тем не менее, я получаю ошибку, когда я пытаюсь использовать эту функцию в классе; я думаю, что это связано с управлением пространством имен. Увидеть ниже:
class MergeSort(object):
def __init__(self, array):
self.array = array
def sort(self):
print('Splitting', self.array)
if len(self.array) > 1:
m = len(self.array)//2
left = self.array[:m]
right = self.array[m:]
sort(left)
sort(right)
i = 0
j = 0
k = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
self.array[k] = left[i]
i += 1
else:
self.array[k] = right[j]
j += 1
k += 1
while i < len(left):
self.array[k] = left[i]
i += 1
k += 1
while j < len(right):
self.array[k] = right[j]
j += 1
k += 1
print('Merging', self.array)
x = MergeSort([1,6,5,2,10,8,7,4,3,9])
x.sort()
Выводит ошибку:
Splitting [1, 6, 5, 2, 10, 8, 7, 4, 3, 9]
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-15-89509f86277e> in <module>()
1 x = MergeSort([1,6,5,2,10,8,7,4,3,9])
----> 2 x.sort()
<ipython-input-14-2bba116f00ce> in sort(self)
11 right = self.array[m:]
12
---> 13 sort(left)
14 sort(right)
15
NameError: name 'sort' is not defined
Мой первоначальный инстинкт, после поиска в Google, заключался в изменении подпрограмм сортировки (слева) и сортировки (справа) путем добавления префикса self., Но это вызывает ошибку позиционного аргумента. Хотелось бы комментарий или два о том, что я не понимаю здесь. И приветствует хорошие голоса, если мой вопрос не глупый, и отрицательные голоса, если это так.
3 ответа
Причина sort(left)
не работает в том, что, как вы уже догадались, вы не можете вызвать метод на self
без указания self
, Отключение означает, что он ищет локальное или глобальное имя sort
не находит и поднимает NameError
,
Причина self.sort(left)
не работает, потому что API, который вы определили, не работает таким образом. Ваш класс принимает список в качестве аргумента конструктора, а затем принимает sort
без аргументов, который действует в списке, переданном во время создания. Таким образом, вы не можете позвонить своим sort
с другим массивом. Если вы попытаетесь self.sort(left)
, вы передаете неправильное количество аргументов, так же, как вызов abs(1, 2)
и вы получите то же самое TypeError
,
Вы должны использовать свой API так, как вы его создали: создать новый MergeSort
Сортировать объект с новым списком, затем вызвать sort
на этом новом объекте:
leftsorter = MergeSort(left)
leftsorter.sort()
rightsorter = MergeSort(right)
rightsorter.sort()
Замена sort(left)
а также sort(right)
компоненты функции sort () в моем классе с
leftsorter = MergeSort(left)
leftsorter.sort()
rightsorter = MergeSort(right)
rightsorter.sort()
(Спасибо, Абарнерт)
В то же время, удаляя отладочные операторы печати из кода (спасибо Evgany P) и избегая повторного использования встроенного имени функции sort (), чтобы избежать путаницы, у меня есть рабочий класс MergeSort.
class MergeSort(object):
def __init__(self, array):
self.array = array
def merge_sort(self):
if len(self.array) > 1:
m = len(self.array)//2
left = self.array[:m]
right = self.array[m:]
leftsorter = MergeSort(left)
leftsorter.merge_sort()
rightsorter = MergeSort(right)
rightsorter.merge_sort()
i = 0
j = 0
k = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
self.array[k] = left[i]
i += 1
else:
self.array[k] = right[j]
j += 1
k += 1
while i < len(left):
self.array[k] = left[i]
i += 1
k += 1
while j < len(right):
self.array[k] = right[j]
j += 1
k += 1
x = MergeSort([3,5,6,2,1,4,10,9,8,7])
x.merge_sort()
x.array
Out []: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Молодцы все!
Вам нужно позвонить self.sort()
в классе.
Большая проблема в том, что ни одна из ваших функций или методов класса ничего не возвращает, только печатает, вас это устраивает?