首先对具有最长项目的列表进行排序 [英] Sort a list with longest items first

查看:74
本文介绍了首先对具有最长项目的列表进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用lambda修改sort的行为.

I am using a lambda to modify the behaviour of sort.

sorted(list, key=lambda item:(item.lower(),len(item)))

对包含元素A1,A2,A3,A,B1,B2,B3,B的列表进行排序,结果为A,A1,A2,A3,B,B1,B2,B3.

Sorting a list containing the elements A1,A2,A3,A,B1,B2,B3,B, the result is A,A1,A2,A3,B,B1,B2,B3.

我期望的排序列表为A1,A2,A3,A,B1,B2,B3,B.

我已经尝试包含len(item)进行排序,但是没有用.如何修改lambda,以代替排序结果?

I've already tried to include the len(item) for sorting, which didn't work. How to modify the lambda so that the sort result is instead?

推荐答案

这里是一种方法:

>>> import functools
>>> def cmp(s, t):
    'Alter lexicographic sort order to make longer keys go *before* any of their prefixes'
    ls, lt = len(s), len(t)
    if ls < lt:   s += t[ls:] + 'x'
    elif lt < ls: t += s[lt:] + 'x'
    if s < t: return -1
    if s > t: return 1
    return 0

>>> sorted(l, key=functools.cmp_to_key(cmp))
['A1', 'A2', 'A3', 'A', 'B1', 'B2', 'B3', 'B']

传统上,字典顺序将较长的字符串排在之后,否则它们的前缀相同(即'abc'在'abcd'之前).

Traditionally, lexicographic sort order longer strings after their otherwise identical prefixes (i.e. 'abc' goes before 'abcd').

为满足您的排序期望,我们首先通过将较长字符串的剩余部分加另一个字符加起来以使其成为两者中的较长者,来修正"较短的字符串:

To meet your sort expectation, we first "fix-up" the shorter string by adding the remaining part of the longer string plus another character to make it the longer of the two:

compare abc to defg     -->  compare abcgx to defg
compare a   to a2       -->  compare a2x to a2

functools.cmp_to_key()工具随后将比较函数转换为键函数.

The functools.cmp_to_key() tool then converts the comparison function to a key function.

这似乎是一项艰巨的工作,但排序期望与内置词典编目排序规则大相径庭.

This may seem like a lot of work, but the sort expectations are very much at odds with the built-in lexicographic sorting rules.

FWIW,这是另一种编写方式,可能会更清晰或更清晰:

FWIW, here's another way of writing it, that might or might not be considered clearer:

def cmp(s, t):
    'Alter lexicographic sort order to make longer keys go *before* any of their prefixes'
    for p, q in zip(s, t):
        if p < q: return -1
        if q < p: return 1
    if len(s) > len(t): return -1
    elif len(t) > len(s): return 1
    return 0

逻辑是:

  • 逐个字符比较直到找到另一对
  • 不同的配对以传统方式确定排序顺序
  • 如果没有不同的货币对,则最长的输入排在最前面.
  • 如果没有对,并且长度相等,则字符串相等.

这篇关于首先对具有最长项目的列表进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆