Schwartzian transform(DSU)

  在了解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[ 1 for  x  in  tmp]

 

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

 

 list[:] =  [x[ 1 for  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[ - 1 for  tup  in  intermed ]

 

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值