Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何对任意可索引集合执行有效的就地排序? 问题:_Python_Sorting_In Place - Fatal编程技术网

Python 如何对任意可索引集合执行有效的就地排序? 问题:

Python 如何对任意可索引集合执行有效的就地排序? 问题:,python,sorting,in-place,Python,Sorting,In Place,如何使用Python的内置排序(或类似)对任意集合进行就地排序(支持\uuuu len\uuuu、\uuu getitem\uuuuu和\uuu setitem\uuuuu方法) 背景 这个问题是由于考虑了以下问题(有点相关)而产生的。假设我有两个长度相等的大列表: hours = [20, 21, 18, 18, 19] minutes = [15, 14, 13, 12, 11] (在本例中表示时间20:15、21:14等) 我想将这些列表按两个列表中的值对(例如zip返回的值)进行适

如何使用Python的内置排序(或类似)对任意集合进行就地排序(支持
\uuuu len\uuuu
\uuu getitem\uuuuu
\uuu setitem\uuuuu
方法)

背景 这个问题是由于考虑了以下问题(有点相关)而产生的。假设我有两个长度相等的大列表:

hours   = [20, 21, 18, 18, 19]
minutes = [15, 14, 13, 12, 11]
(在本例中表示时间20:15、21:14等)

我想将这些列表按两个列表中的值对(例如
zip
返回的值)进行适当排序,以给出:

hours   = [18, 18, 19, 20, 21]
minutes = [12, 13, 11, 15, 14]
可以通过将两个列表封装到自定义集合中来实现这一点,该集合在索引时使用成对的值,然后对该集合进行排序

下面是收集类:

class Times:
    
    def __init__(self, hours, minutes):
        if len(hours) != len(minutes):
            raise ValueError('lists must be of same length')
        self.hours = hours
        self.minutes = minutes

    def __getitem__(self, i):
        return (self.hours[i], self.minutes[i])

    def __setitem__(self, i, vals):
        self.hours[i], self.minutes[i] = vals

    def __len__(self):
        return len(self.hours)
我们可以通过对顶级集合进行就地排序,以内存高效的方式对底层列表进行排序。但是下面的示例使用了CPU效率低下的排序算法

def bubble_sort(x):
    n = len(x)
    for last in range(n-1, 0, -1): 
        for pos in range(last):
              if x[pos] > x[pos+1] : 
                  x[pos], x[pos+1] = x[pos+1], x[pos] 

hours   = [20, 21, 18, 18, 19]
minutes = [15, 14, 13, 12, 11]
times = Times(hours, minutes)

bubble_sort(times)

print(hours)     # [18, 18, 19, 20, 21]
print(minutes)   # [12, 13, 11, 15, 14]
或者,我们可以使用Python更高效的内置
排序
,但是我们分配了更多的内存,因为它没有进行排序

hours   = [20, 21, 18, 18, 19]
minutes = [15, 14, 13, 12, 11]
times = Times(hours, minutes)

for i, v in enumerate(sorted(times)):
    times[i] = v

print(hours)    # [18, 18, 19, 20, 21]
print(minutes)  # [12, 13, 11, 15, 14]
因此,希望能够使用Python的内置排序(或类似的东西)进行就地排序。尝试在列表以外的其他对象上使用
list.sort
失败--不支持:

>>> list.sort(times)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor 'sort' requires a 'list' object but received a 'instance'
>列表.排序(次)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:描述符“sort”需要“list”对象,但收到“instance”

如何做到这一点?

我认为您必须手动对这些内容进行排序,不能使用库功能。使用“就地”是什么意思?@superbrain我的意思是修改集合,而不是生成单独的副本。基本上在这里,我也对使用O(1)量的额外内存感兴趣。O(1)额外内存排除了任何
列表。排序
解决方案,因为这不是O(1)而是O(n)。有趣的是,我没有意识到这一点。(这里还需要注意的是,我将暂时离线,因此稍后将对任何进一步的评论作出回应。)