我正在尝试编写一个选择排序算法,用于对从最低到最高的数字列表进行排序。
def sortlh(numList):
if type(numList) != list:
print("Input must be a list of numbers.")
else:
inf = float("inf")
sortList = [0]*len(numList)
count = 0
while count < len(numList):
index = 0
indexLowest = 0
lowest = numList[index]
while index < (len(numList) - 1):
if numList[index + 1] < numList[index]:
lowest = numList[index + 1]
indexLowest = index + 1
index = index + 1
else:
index = index + 1
sortList[count] = lowest
numList[indexLowest] = inf
count = count + 1
return sortList
当我运行此代码时:
sortlh([9,8,7,6,5,4,3,2,1])
我得到(正如预期的那样):
[1, 2, 3, 4, 5, 6, 7, 8, 9]
然而,当我尝试另一个例子时,我得到:
sortlh([1,3,2,4,5,7,6,9,8])
[8,6,9,2,4,5,7,1,3]
有谁看到这里发生了什么?
答案 0 :(得分:1)
以下是我建议您重写程序的方法。
def sortlh(lst_input):
lst = list(lst_input) # make a copy of lst_input
i = 0
while i < len(lst):
j = i + 1
i_lowest = i
lowest = lst[i_lowest]
while j < len(lst):
if lst[j] < lowest:
i_lowest = j
lowest = lst[i_lowest]
j += 1
lst[i], lst[i_lowest] = lst[i_lowest], lst[i] # swap
i += 1
return lst
test = [9,8,7,6,5,4,3,2,1]
assert sortlh(test) == sorted(test)
test = [1,3,2,4,5,7,6,9,8]
assert sortlh(test) == sorted(test)
我们不测试输入的类型。任何像列表一样的东西都可以工作,甚至迭代器都可以工作。
我们不会“改变”原始输入列表。我们只处理数据副本。
当我们找到最小的数字时,我们将它与第一个数字交换,然后只查看剩余的数字。因此,我们在每个循环上的工作量较少,因为我们的未分类数量越来越少。
编辑:
如果您是初学者,这部分可能看起来太棘手了。如果它让你感到困惑或者你不喜欢它,那就暂时忽略它。
这是在Python中解决此问题的更高级方法。内循环只查找最小数字和最小数字的索引。我们可以使用Python内置函数min()
来执行此操作!
我们构建一个“生成器表达式”,循环遍历列表,产生元组。每个元组都是数字和位置。由于我们希望较低的数字排序较低,我们将数字放在元组的第一位,以便min()
可以正确地比较元组。然后min()
将找到最低元组,我们得到值和索引。
此外,外部循环现在是for
循环enumerate
而不是使用索引的while
循环。
def sortlh(lst_input):
lst = list(lst_input) # make a copy of lst_input
for i, x in enumerate(lst):
lowest, i_lowest = min((n, j) for j, n in enumerate(lst) if j >= i)
lst[i], lst[i_lowest] = lst[i_lowest], lst[i] # swap
return lst
test = [9,8,7,6,5,4,3,2,1]
assert sortlh(test) == sorted(test)
test = [1,3,2,4,5,7,6,9,8]
assert sortlh(test) == sorted(test)