高级列表排序Python

时间:2013-11-15 06:35:52

标签: python list sorting dictionary sorted

我正在尝试对字体进行排序:

d = {'+A':234, '-B':212, 'A':454, '-C':991, '-A':124}

我想按密钥对其进行排序,使其形式为:

+A, A, -A, +B, B, -B, etc

我一直在尝试使用sorted(d, key=lambda x: (x[1], x[0]) if len(x) == 2 else x[0]) 但我似乎无法找到任何正确排序符号的方法,因为它们在ascii图表上的顺序不正确。我做错了什么?

3 个答案:

答案 0 :(得分:7)

一种简单的方法

rank = ['+A', 'A', '-A', '+B', 'B', '-B', ...]
sorted(d.items(), key=lambda i: rank.index(i[0]))

如果有很多排名,最好使用dict

rank = {'+A': 0, 'A': 1, '-A': 2, '+B': 3, 'B': 4, '-B': 5, ...}
sorted(d.items(), key=lambda i: rank[i[0]])

您可以使用这样的lambda函数。请注意,使用向后切片确保字母在其修饰符之前进行排序非常重要。

sorted(d.items(), key=lambda i:(','+i[0])[::-1])

但我认为明确的rank更清晰,不容易出现像@Hari答案那样的错误。 (到目前为止,有5人投票赞成该错误)

如果你确实需要按键排序(为什么?),你可以简单地使用rank.get而不是lambda函数:

>>> rank = {'+A': 0, 'A': 1, '-A': 2, '+B': 3, 'B': 4, '-B': 5, '+C': 6, 'C': 7, '-C': 8}
>>> d = {'+A':234, '-B':212, 'A':454, '-C':991, '-A':124}
>>> sorted(d, key=rank.get)
['+A', 'A', '-A', '-B', '-C']

但最好完全跳过sorted

>>> rank = ['+A', 'A', '-A', '+B', 'B', '-B', '+C', 'C', '-C']
>>> d = {'+A':234, '-B':212, 'A':454, '-C':991, '-A':124}
>>> [k for k in rank if k in d]
['+A', 'A', '-A', '-B', '-C']

如果您不想输入所有'

>>> rank = '+A A -A +B B -B +C C -C'.split()

答案 1 :(得分:6)

这应该有效:

sorted(d, key=lambda x: (x[1], x[0]) if len(x) == 2 else (x[0], ','))

,的{​​{3}}位于+-之间,因此您可以在底部放置一个虚拟,进行比较。

>>> d = {'+A':234, '-B':212, 'A':454, '-C':991, '-A':124, '+B':1, 'B':98, '+C':232, 'C':23}
>>> sorted(d, key=lambda x: (x[1], x[0]) if len(x) == 2 else (x[0], ','))
['+A', 'A', '-A', '+B', 'B', '-B', '+C', 'C', '-C']

您也可以简单地反转键并为比较器附加,

sorted(d, key=lambda x: x[::-1] + ',')

所以+ A,A,-A被比较为A+,AA-,

答案 2 :(得分:1)

我排序:

  • 只是字母 - 剥离领先-+
  • +( - 1)上加上另一个权重,所以它首先出现,-所以它是最后一个(1)否则为0

例如:

sorted(d.iteritems(), key=lambda L: (L[0].lstrip('-+'), {'-': 1, '+': -1}.get(L[0][0], 0)))
# [('+A', 234), ('A', 454), ('-A', 124), ('-B', 212), ('-C', 991)]