Schwartzian transform(DSU)

Schwartzian Transform是一种高效的排序技巧,适用于计算密集型任务。它通过预处理元素以提取排序键值,避免了对复杂元素重复计算,提高了排序效率。

  在了解python的时候发现Schwartzian transform这条规则,是针对computing intensive排序的一种高效手段,也被称作“装饰-排序-去装饰”(decorate-sort-undecorate),在Knuth的神作有详细介绍(当然我没有去翻)

  一般地,在python的排序中, 我们提供一个compare函数,然后交由python内建的sort处理,比如

 

def cmp(a,b):
    
if a>b:return 1
    
elif a<b:return -1
    
else:return 0

if __name__ == '__main__':
    ls 
= [1,8,5,3]
    ls.sort(cmp)
    
print ls

 你将会得到排好序的[1,3,5,8]

  但是,有时如果cmp过于复杂,直接这样做效率会很低,于是 Schwartzian transform这种最早出现在perl中的编程惯例便显现出优越性,它的主要思想是:

1. 对list中的复杂元素进行处理,提取出与排序相关的key,与原元素组合成为tupple

2.调用内建排序算法(对key)

3.提取出排好序的list

以下是伪代码:

def sortDSU(list)
    tmp 
= [(x.key(), x) for x in list] #这里key()表示提取排序相关的key值
    tmp.sort()  
    
return [x[1for x in tmp]

 

 当然如果你想实现in-place排序,最后一句换为

 

 list[:]= [x[1for x in tmp]

 ========================================================

总结:

DSU避免了对复杂元素反复计算key值,达到了memoization的效果

 

 最后,贴一个python cookbook上的例子:

Sorting a List of Objects by an Attribute of the Objects

 按照指定属性排序
def sort_by_attr(seq, attr):
    
import operator

    intermed 
= map(None, map(getattr, seq, (attr,)*len(seq)),
        xrange(len(seq)), seq)
    intermed.sort(  )
    
return map(operator.getitem, intermed, (-1,)*len(intermed))

如果对map不是很熟,另一种表述可能会更清晰

def sort_by_attr2(seq, attr):
    intermed 
= [(getattr(seq[i], attr), i, seq[i]) for i in xrange(len(seq))]
    intermed.sort(  )
    
return [ tup[-1for tup in intermed ]

 

 

转载于:https://www.cnblogs.com/xiaobenzhu/archive/2009/11/14/1603060.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值