Python 如何对任意可索引集合执行有效的就地排序? 问题:
如何使用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返回的值)进行适
\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)。有趣的是,我没有意识到这一点。(这里还需要注意的是,我将暂时离线,因此稍后将对任何进一步的评论作出回应。)