排序字符串矩阵[[a,b,c],..]通过a,-c,b来维持秩序



我有一个Python中三个字符串的列表,例如

m = [['pig', 'quartz', '1'], ['pork', 'nails', '1'], ...]

我想按索引0排序,然后按相反顺序按索引2排序,再按索引1排序。在排序的每一步,我都希望保持其他列强加的顺序。例如,

pork       barn         4
pork       barn2        4
pork       nails        1
pig        quartz       1
quinoa     pail         1
quinoa     quatern      1
quail      quatern      1
radish     barn         1
radish     barn2        1
radish     inbox        3
radish     snow         1

将变成:

pig        quartz       1
pork       barn         4
pork       barn2        4
pork       nails        1
quail      quatern      1
quinoa     pail         1
quinoa     quatern      1
radish     inbox        3    <-
radish     barn         1
radish     barn2        1
radish     snow         1

也就是说,按第一列排序,然后在每组第一列(猪、猪肉、鹌鹑…)内,按第三列反向排序,然后按每组第一列第三列((猪,1)、(猪肉,4)、,按第二列排序。

我怎么能做得这么好?从概念上讲,如果operator.itemgetter()可以将排序顺序和索引一起编码,我会想要类似m.sort(key=operator.itemgetter(0, -2, 1))的东西。

def key(item):
    return item[0], -int(item[2]), item[1]
m.sort(key = key)

PS。cmp关键字参数已从Python3中删除。为了将来的兼容性,您可能希望继续使用key

我会尝试这样的东西:

def sort_key(a, b, c):
   return (a, -int(c) , b)           
m.sort(key = lambda row: sort_key(*row))

使用自定义比较函数:

def compare_triples(a, b):
    ret=cmp(a[0], b[0])
    if ret: return ret
    ret=cmp(b[2], a[2])
    if ret: return ret
    return cmp(a[1], b[1])
for i in m: print i
print "-" * 79
m2=sorted(m, cmp=compare_triples)
for i in m2: print i

比较函数不是最优的,可以重写为:

def compare_triples(a, b):
    return cmp((a[0], b[2], a[1]), (b[0], a[2], b[1]))

正如其他人所指出的,这也会奏效:

def sort_key(a):
    return a[0], -int(a[2]), a[1]
for i in sorted(m, key=sort_key): print i

最新更新