Python排序 - 半忽略大小写(a,aa,A,AA,b,bb,B,BB ...)

时间:2018-06-15 09:30:36

标签: python sorting

如何对列表进行排序以结束:

['a', 'aa', 'aaa', 'A', 'AA', 'AAA', 'b', 'bb', 'bbb', 'B', 'BB', 'BBB']

为方便起见,假设它的洗牌版本:

['bb', 'a', 'B', 'BB', 'AAA', 'BBB', 'b', 'aa', 'aaa', 'A', 'AA', 'bbb']

我尝试通过忽略大小写进行排序:

l = sorted(l, key=lambda x: x.lower())

会产生['a', 'A', 'aa', 'AA', 'aaa', 'AAA']

根据以下答案,混合情况有两种解决方案,我不确定哪种情况更好。

L = ['ABC1', 'abc1', 'ABC2', 'abc2', 'Abc']
l = sorted(L, key=lambda x: "".join([y.lower() + y.swapcase() for y in x]))
print(l)
l = sorted(L, key=lambda x: [(c.lower(), c.isupper()) for c in x])
print(l)

3 个答案:

答案 0 :(得分:9)

您可以将sorted()与自定义键功能一起使用:

>>> L = ['bb', 'a', 'B', 'BB', 'AAA', 'BBB', 'b', 'aa', 'aaa', 'A', 'AA', 'bbb']
>>> sorted(L, key=lambda x: (x[0].lower(), x[0].isupper(), len(x)))
['a', 'aa', 'aaa', 'A', 'AA', 'AAA', 'b', 'bb', 'bbb', 'B', 'BB', 'BBB']

这是通过首先比较每个元素的第一个小写字母,然后是元素的大小写,最后是它的长度来实现的。

P.S。要处理混合大小写和混合字符元素,您需要比较单个字符的元组,例如:

>>> L = ['ab', 'aA', 'bb', 'a', 'B', 'BB', 'b', 'aa', 'A', 'AA']
>>> sorted(L, key=lambda x: [(c.lower(), c.isupper()) for c in x])
['a', 'aa', 'aA', 'ab', 'A', 'AA', 'b', 'bb', 'B', 'BB']

答案 1 :(得分:6)

TLDR

result = sorted(lst, key=lambda s: [(c.lower(), c.isupper()) for c in s])

您可以将每个字符串转换为元组列表,每个字符一个。角色c的元组采用(c.lower(), c.isupper())形式。通常的列表比较给出了您想要的排序。

lst = ["a", "aa", "aaa", "A", "AA", "AAA", "b", "bb", "bbb", "B", "BB", "BBB"]

lsts = [[(c.lower(), c.isupper()) for c in s] for s in lst]

# [[('a', False)],
# [('a', False), ('a', False)],
# [('a', False), ('a', False), ('a', False)],
# [('a', True)],
# [('a', True), ('a', True)],
# [('a', True), ('a', True), ('a', True)],
# [('b', False)],
# [('b', False), ('b', False)],
# [('b', False), ('b', False), ('b', False)],
# [('b', True)],
# [('b', True), ('b', True)],
# [('b', True), ('b', True), ('b', True)]]

res = ["".join(c.upper() if u else c for c, u in ls) for ls in lsts]

恢复结果:

['a', 'aa', 'aaa', 'A', 'AA', 'AAA', 'b', 'bb', 'bbb', 'B', 'BB', 'BBB']

请注意,有许多不同的方法来命令与OP原始示例一致的混合大小写元素。这种方法是我能想到的唯一合理的方法,它来自反对称的顺序关系。特别是,这种类型不允许使用不相等的等效元素。

例如,['aAa', 'aaA']['aaA', 'aAa']将导致['aaA', 'aAa']的输出相同。

答案 2 :(得分:2)

简短回答:

sorted(l, key=lambda x: "".join([y.lower() + y.swapcase() for y in x]))

每个单词通过加倍每个字母进行转换,第一个字母是字母的较低版本,第二个字母是swaped版本。交换第二个字母是为了将小写字母排在大写之前。