我列表中特定部分的最小数字
Posted
技术标签:
【中文标题】我列表中特定部分的最小数字【英文标题】:Smallest number in a particular part of my list 【发布时间】:2014-06-20 18:34:59 【问题描述】:我有一个关于 python 的问题。我必须以特定方式对随机数列表进行排序(不允许使用sort()
)。我会尽力解释:
我必须搜索最小的数字,并将这个数字与列表中第一个位置的数字交换。
然后,我再次搜索最小的数字,但这次忽略列表中的第一个数字,因为这个数字已经排序。所以,我应该开始搜索从第二个数字(索引 1)到列表末尾的最小数字。然后找到的最小数字应该与列表中的第二个数字交换(因此索引 1)。
我希望你能理解我的问题。这是我到目前为止编写的代码,但出现错误和/或排序不正确。
array = random_integers(10,size=10)
my_list = list(array)
for i in range(len(my_list)):
print my_list
a = min(my_list[i:len(my_list)])
b = my_list.index(a)
my_list[i],my_list[b]=my_list[b],my_list[i]
print my_list
我认为我的范围有问题,并且
a = min(my_list[i:len(my_list)])
我想搜索最小的数字,但不在整个列表中,我该怎么做?
【问题讨论】:
基本上你想在不使用任何内置方法的情况下对列表进行排序? 是的,我必须在不使用内置方法的情况下以这种特殊方式对列表进行排序.. 你听说过归并排序吗? en.wikipedia.org/wiki/Merge_sort 这种算法称为选择排序。它通常作为一个练习来介绍排序。 我想学习归并排序不会有什么坏处。 【参考方案1】:问题出现在这一行:
b = my_list.index(a)
因为这会在my_list
的all 中搜索a
的第一次出现。如果相同的数字出现两次,那么b
将始终对应于最小的此类索引,可能小于i
。所以你最终可能会移动一个已经排序的数字。
显而易见的尝试是在调用index
之前对my_list
进行切片:
my_list[i:].index(a)
但请注意,索引将返回介于 0
和 N-i
之间的值。我们想要i
和N
之间的数字。所以一定要在结果中加上i
:
b = my_list[i:].index(a)+i
因此,修复现有代码的最简单方法是:
for i in range(len(my_list)):
a = min(my_list[i:])
b = my_list[i:].index(a)+i
my_list[i], my_list[b] = my_list[b], my_list[i]
但请注意min
正在搜索my_list[i:]
中的所有项目,然后对index
的调用再次遍历同一个列表。您可以像这样在一次遍历中找到b
:
b = min(range(i, N), key=my_list.__getitem__)
演示:
import numpy as np
array = np.random.random_integers(10,size=10)
my_list = list(array)
N = len(my_list)
for i in range(N):
b = min(range(i, N), key=my_list.__getitem__)
my_list[i], my_list[b] = my_list[b], my_list[i]
print my_list
产量
[3, 10, 9, 6, 5, 3, 6, 8, 8, 4]
[3, 3, 9, 6, 5, 10, 6, 8, 8, 4]
[3, 3, 4, 6, 5, 10, 6, 8, 8, 9]
[3, 3, 4, 5, 6, 10, 6, 8, 8, 9]
[3, 3, 4, 5, 6, 10, 6, 8, 8, 9]
[3, 3, 4, 5, 6, 6, 10, 8, 8, 9]
[3, 3, 4, 5, 6, 6, 8, 10, 8, 9]
[3, 3, 4, 5, 6, 6, 8, 8, 10, 9]
[3, 3, 4, 5, 6, 6, 8, 8, 9, 10]
[3, 3, 4, 5, 6, 6, 8, 8, 9, 10]
【讨论】:
请注意,无需继续使用len(my_list)
(或N
)-my_list[i:]
默认在列表末尾结束。
如果你打算使用 numpy 那么为什么不使用.argmin()
?
@Scorpion_God:我不知道 OP 是否真的想要一个以 NumPy 为中心的解决方案。毕竟,他正在实施选择排序。所以我这里只用了numpy来为OP的random_integers(10,size=10)
找个意义。【参考方案2】:
如果您想要列表中的最小数字,您可以使用min()
。如果您想要列表的一部分,您可以使用列表切片:my_list[1:]
。将两者放在一起,您会从列表的一部分中获得最小的数字。但是,您不需要这样做,因为您可以从列表中 .pop()
代替。
sorted_list = []
while my_list:
n = min(my_list)
sorted_list.append(my_list.pop(my_list.index(n)))
如果您使用的是 numpy 数组,那么您可以使用 .argmin()
方法而不是 my_list.index(min(my_list))
。
虽然这种类型的排序有利于介绍,但效率不高。您可能需要考虑查看合并排序,以及 Python 的内置 timsort。
【讨论】:
以上是关于我列表中特定部分的最小数字的主要内容,如果未能解决你的问题,请参考以下文章
Python 3,如果列表中包含特定的东西,如何删除部分元素3 [重复]
如何查找特定的数字长度,并使用 Notepad++ 删除/过滤其余部分?