2015-02-12 2 views
0

Я не могу понять, почему программа питона производит следующий вывод:Что случилось с моим выбором выбора python?

c:\Python Programs>selection_sort.py 

[7, 4, 2, 9, 6] 

[2, 4, 7, 9, 6] 
[2, 6, 7, 9, 4] 
[2, 6, 4, 9, 7] 
Traceback (most recent call last): 
    File "J:\Python Programs\Python Practice\selection_sort.py", line 11, in <modu 
le> 
    num_list[i], num_list[min_num] = num_list[min_num], num_list[i] 
IndexError: list index out of range 

c:\Python Programs> 

Я думаю, что я понимаю, индекс списка из диапазона части, но я не уверен, о том, почему 6 становится вторым элементом когда i = 1. Разве машина не читала мое заявление if?

Вот код ниже:

num_list = [7,4,2,9,6] 
len_num_list = len(num_list) 
print num_list 
print""#print empty string to separate the original list from the following iterations 
for i in range(0,len_num_list): 
    min_num = min(num_list[i:]) #finds minimum number in list to the right of i 
    if min_num>num_list[i]: 
     min_num = num_list[i] 
    num_list[i], num_list[min_num] = num_list[min_num], num_list[i] 
    print num_list 

ответ

0

Проблема заключается в том, что min(num_list[i:]) возвращает номер из списка, а не индекс в этот список. Вы можете использовать метод index, чтобы получить индекс, соответствующий min(num_list[i:]). Таким образом, попробуйте:

num_list = [7,4,2,9,6] 
len_num_list = len(num_list) 
print num_list 
print""#print empty string to separate the original list from the following iterations_ 
for i in range(0,len_num_list): 
    min_num = min(num_list[i:]) #finds minimum number in list to the right of i 
    j = num_list.index(min_num) 
    if min_num>num_list[i]: 
     min_num = num_list[i] 
    num_list[i], num_list[j] = num_list[j], num_list[i] 
    print num_list 

Это производит вывод:

[7, 4, 2, 9, 6] 

[2, 4, 7, 9, 6] 
[2, 4, 7, 9, 6] 
[2, 4, 6, 9, 7] 
[2, 4, 6, 7, 9] 
[2, 4, 6, 7, 9] 
1

Первое, отметим, что в вашем фрагменте кода:

min_num = min(num_list[i:]) #finds minimum number in list to the right of i 
if min_num>num_list[i]: 
    min_num = num_list[i] 

завещанию if никогда, никогда не матч - поскольку min_num является минимальным под-списком, начинающимся с num_list[i], он ни при каких обстоятельствах не может быть, е больше, чем последнее.

Итак, проиграйте последние два из этих трех утверждений - они примерно так же полезны, как проверка if 2+2 != 4: :-).

Далее, заметим, что вы действительно не хотите min_num быть значение (который является то, что ваш призыв к min дает вам) - Вы хотите, чтобы это было индекс в список, для того, выполнить обмен:

num_list[i], num_list[min_num] = num_list[min_num], num_list[i] 

Но попытка превратить значение в индекс с помощью метода index довольно ненадежный путь: если список ввода может иметь любые дубликаты, index всегда найдет первый из них, и это вполне может запутать вас. Я бы лично решил не ходить туда.

скорее рассмотреть более прямой путь нахождения минимального индекса с использованием соответствующего значения через key= особенности min! То есть:

for i in range(0,len_num_list): 
    min_ind = min(range(i, len_num_list), 
        key=lambda j: num_list[j]) 
    num_list[i], num_list[min_ind] = num_list[min_ind], num_list[i] 
    print num_list 

Если вы не знакомы с key= особенностью многих Python встроенных модулей (min, max, sorted, ...), это действительно хорошая вещь, чтобы учиться.

Сортирует (или дает минимальную или максимальную или) определенную последовательность, при этом сравнения выполняются после прохождения каждого элемента последовательности через «функцию извлечения ключа», которую вы передаете как key=. Здесь вы хотите «индекс минимума», и вы получите это, выбрав индекс min с key= соответствующего поиска каждого индекса в списке.

Я лично не нравится лямбда и может использовать key=numlist.__getitem__, но это не очень считываемый - наиболее читаемый всегда использовать def (и я бы сделал то же самое для этой функциональности подкачки), например ..:

def item_in_list(index): return num_list[index] 
def swap(i, j): num_list[i], num_list[j] = num_list[j], num_list[i] 
for i in range(0,len_num_list): 
    min_ind = min(range(i, len_num_list), key=item_in_list) 
    swap(i, min_ind) 
    print num_list 

, который я считаю самым читаемым и изящным подходом к этой задаче.