【问题标题】:Advanced List sorting Python高级列表排序 Python
【发布时间】:2013-11-28 11:38:14
【问题描述】:

我正在尝试对格式如下的字典进行排序:

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 图表上的顺序不正确。我做错了什么?

【问题讨论】:

  • sorted(d,...) 只是将 keys 传递给 lambda 函数。

标签: python list sorting dictionary sorted


【解决方案1】:

一种简单的方法

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()

【讨论】:

    【解决方案2】:

    我会排序:

    • 只是字母 - 去掉前导 -+
    • + (-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)]
    

    【讨论】:

    • 你也可以用L[0][-1]代替lstrip
    【解决方案3】:

    这应该可行:

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

    ,ascii value 位于 +- 之间,因此您可以在末尾放置一个虚拟的 , 进行比较。

    >>> 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-,

    【讨论】:

    • 这似乎有效,因为您的示例中没有'+B' 'B' '+C' 'C'
    • @gnibbler 很好,我应该把字母表放在首位。固定!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多