简体   繁体   English

我的python选择排序有什么问题?

[英]What's wrong with my python selection sort?

I can't figure out why the python program produces the following output: 我不知道为什么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>

I think I understand the list index out of range part, but I'm not sure about why the 6 becomes the second element when i = 1. Didn't the machine read my if statement? 我想我了解列表索引超出范围的部分,但是我不确定为什么当i = 1时6成为第二个元素。机器没有读取我的if语句吗?

Here is the code below: 这是下面的代码:

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  

First, let's note that in your snippet: 首先,请注意您的代码段中:

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]

the if will never, ever match -- since min_num is the minimum of a sub-list that starts with num_list[i] , it can't possibly, ever, under any circumstance, be greater than the latter. if 永远不会匹配-因为min_num是以num_list[i]开头的子列表的最小值,所以在任何情况下都不可能大于后者。

So, lose the last two of these three statements -- they're about as useful as checking if 2+2 != 4: :-). 因此,请丢失这三个语句中的最后两个-它们与检查if 2+2 != 4: :-)一样有用。

Next, let's note that you don't really want min_num to be a value (which is what your call to min gives you) -- you want it to be an index into the list, in order to perform the swap: 接下来,请注意,您实际上并不希望min_num是一个 (这是您对min的调用所提供的),而是希望它成为列表的索引 ,以便执行交换:

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

But trying to turn a value into an index via the index method is quite an iffy path: if the input list can have any duplicates, index will always locate the first one of them, and that might quite possibly tangle you up. 但是,尝试通过index方法将值转换为索引是很困难的:如果输入列表可以有任何重复项,则index总是会找到它们中的第一个,这很可能使您纠结。 I personally would choose not to go there. 我个人会选择不去那里。

Rather consider the more direct path of finding the minimum index using the corresponding value via the key= feature of min ! 而是考虑通过min key=key=功能使用相应查找最小索引的更直接路径。 Ie: 即:

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

If you're not familiar with the key= feature of many Python built-ins ( min , max , sorted , ...), it's really a good thing to learn. 如果您不熟悉许多Python内置插件( minmaxsorted ,...)的key=功能,那确实是一件好事。

It sorts (or gives the min, or max, or) a certain sequence, with the comparisons done after passing each item of the sequence through the "key extraction function" you pass as key= . 它对某个序列进行排序(或给出min或max或),并在将序列的每个项目传递给您作为key=传递的“密钥提取函数”之后进行比较。 Here, you want "the index of the minimum" and you get that by picking the min index with a key= of the corresponding look-up of each index into the list. 在这里,您需要“最小值的索引”,然后通过使用key=来选择最小值索引,该索引的每个索引对应于列表中的每个索引。

I personally dislike lambda and might use key=numlist.__getitem__ , but that's not very readable either -- most readable is always to use def (and I'd do the same for that swap functionality), eg..: 我个人不喜欢lambda,并且可能会使用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

which I find to be the most readable and elegant approach to this task. 我发现这是执行此任务最易读,最优雅的方法。

The problem is that min(num_list[i:]) returns a number from the list, not an index into that list. 问题是min(num_list[i:])从列表中返回一个数字,而不是该列表中的索引。 You can use the index method to get the index corresponding to min(num_list[i:]) . 您可以使用index方法获取与min(num_list[i:])对应的索引。 Thus, try: 因此,请尝试:

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

This produces the output: 产生输出:

[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]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM