帮助排序:第一本,然后由该

我有元组我想排序的列表,并可以使用一些帮助。

我希望在元组排序的现场看起来像“XXX_YYY”。 首先,我想集团以相反的顺序XXX值,然后,这些组中,我希望把YYY值在正常排序。 (注:我一样开心,其实,排序在这样的元组的第二个项目,反序第一个字 ,正常秩序 。)

这里是什么,我有一个例子,我想到底...不知道该怎么做。

mylist = [ (u'community_news', u'Community: News & Information'), (u'kf_video', u'KF: Video'), (u'community_video', u'Community: Video'), (u'kf_news', u'KF: News & Information'), (u'kf_magazine', u'KF: Magazine') ]

我想进行某种形式的sort()这个名单,这将改变输出到:

sorted = [ (u'kf_magazine', u'KF: Magazine'), (u'kf_news', u'KF: News & Information'), (u'kf_video', u'KF: Video'), (u'community_news', u'Community: News & Information'), (u'community_video', u'Community: Video'), ]

我怀疑有可能是一个Python化的方式来处理这个问题,但我不能环绕它我的头。

--------------解决方案-------------

对于排序自定义比较函数 ,如在现有的答案建议,也可以很容易地进行升序和降序的订单组合-但他们有严重的性能问题,并在Python 3已被删除,只留下首选的自定义方法-自定义键提取功能...快得多,但更细腻使用了比较少见的用例的混合升序/降序排序。

在Python 2.*它支持两种类型的自定义不能同时在相同的调用sortsorted :-),自定义比较函数可以通过为cmp=命名参数; 或者,自定义密钥提取功能,可以通过一个key=命名参数。 在Python 3.*只有后者选项。

这绝对是值得理解的关键提取方法,即使你认为你刚刚解决你的问题,定制比较法,而不是:不只是性能,但对于未来proofness(Python 3中)和通用性(该key=方法也适用于minmax itertools.groupby ......远远超过了更普遍的cmp=办法!)。

主要提取是非常简单的,当所有的关键子域进行排序以同样的方式(全部升序或降序全) - 你只提取他们。 它仍然是相当容易,如果子字段是走“其他方式”是数字(你只是改变自己的标志,同时提取); 微妙的情况下,正是一个你 - 多字符串字段必须在oppposite的方式进行比较。

一个相当简单的方法来解决你的问题,是一个很小的垫片类:

class Reverser(object):
def __init__(self, s): self.s = s
def __lt__(self, other): return other.s < self.s
def __eq__(self, other): return other.s == self.s

请注意,您只需要提供__lt____eq__<==操作符) - sort和朋友合成所有其他的比较,如果需要的话,基于这两个。

所以,有了这些小的辅助工具,我们可以轻松地继续...:

def getkey(tup):
a, b = tup[0].split('_')
return Reverser(a), b

my_list.sort(key=getkey)

正如你看到的,一旦你“获得”反向和密钥提取概念,你付出基本上没有价格,利用密钥提取,而不是自定义比较:我建议该码是4报表的反向类(你可以写一次投入你的“好东西包”模块的地方),三为重点提取功能,当然还有一个用于的sortsorted电话-一共有八VS自定义比较法的4 + 1 = = 5在最紧凑的形式(例如:一个使用CMP或者用符号的改变,或CMP与交换参数)。 三种说法都没有太大的代价,关键提取的优势 - !)

性能显然不是这样的短名单的一个大问题,但更温和较长(10次)之一... ...:

# my_list as in the Q, my_cmp as per top A, getkey as here

def bycmp():
return sorted(my_list*10, cmp=my_cmp)

def bykey():
return sorted(my_list*10, key=getkey)

...

$ python -mtimeit -s'import so' 'so.bykey()'
1000 loops, best of 3: 548 usec per loop
$ python -mtimeit -s'import so' 'so.bycmp()'
1000 loops, best of 3: 995 usec per loop

也就是说, key=方式已经呈现出近两倍(排序列表快一倍),性能提升工作的50项列表时-非常值得的价格适中的“8号线,而不是5”,特别是与其他所有的优点我已经提到过!

def my_cmp(x, y):
x1, x2 = x[0].split('_')
y1, y2 = y[0].split('_')
return -cmp(x1, y1) or cmp(x2, y2)

my_list = [
(u'community_news', u'Community: News & Information'),
(u'kf_video', u'KF: Video'),
(u'community_video', u'Community: Video'),
(u'kf_news', u'KF: News & Information'),
(u'kf_magazine', u'KF: Magazine')
]

sorted_list = [
(u'kf_magazine', u'KF: Magazine'),
(u'kf_news', u'KF: News & Information'),
(u'kf_video', u'KF: Video'),
(u'community_news', u'Community: News & Information'),
(u'community_video', u'Community: Video'),
]

my_list.sort(cmp=my_cmp)
assert my_list == sorted_list

>>> def my_cmp(tuple_1, tuple_2):
xxx_1, yyy_1 = tuple_1[0].split('_')
xxx_2, yyy_2 = tuple_2[0].split('_')
if xxx_1 > xxx_2:
return -1
elif xxx_1 < xxx_2:
return 1
else:
return cmp(yyy_1, yyy_2)

>>> import pprint
>>> pprint.pprint(sorted(mylist, my_cmp))
[(u'kf_magazine', u'KF: Magazine'),
(u'kf_news', u'KF: News & Information'),
(u'kf_video', u'KF: Video'),
(u'community_news', u'Community: News & Information'),
(u'community_video', u'Community: Video')]

不是最漂亮的解决方案在全球...

分类:蟒蛇 时间:2015-03-15 人气:4
本文关键词: 蟒蛇,整理
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.537 (s). 10 q(s)