天道酬勤,学无止境

How to sort a dictionary by two elements, reversing only one

问题

考虑以下字典:

data = {'A':{'total':3},
        'B':{'total':5},
        'C':{'total':0},
        'D':{'total':0},
       }

以上所需的顺序是 B、A、C、D。按总降序排列,然后按升序键。

当我调用sorted(data, key=lambda x: (data[x]['total'], x), reverse=True)我得到 B,A,D,C 因为在两个键上都调用了 reverse 。

有没有有效的方法来解决这个问题?

回答1

负数进行排序,这将使总数反向排列,而无需使用reverse=True 。 然后按正序在密钥上打破关系:

sorted(data, key=lambda x: (-data[x]['total'], x))

演示:

>>> data = {'A':{'total':3},
...         'B':{'total':5},
...         'C':{'total':0},
...         'D':{'total':0},
...        }
>>> sorted(data, key=lambda x: (-data[x]['total'], x))
['B', 'A', 'C', 'D']

此技巧仅适用于排序键中的数字组件; 如果您有多个键需要更改数字的排序方向,则必须进行多遍排序(多次排序,从最后一个键到第一个键):

# when you can't take advantage of numerical values to reverse on
# you need to sort repeatedly from last key to first.
# Here, sort forward by dict key, then in reverse by total
bykey = sorted(data)
final = sorted(bykey, key=lambda x: data[x]['total'], reverse=True)

这是因为 Python 排序算法是稳定的; 如果这两个元素的当前排序键结果相等,则两个元素保持它们的相对位置。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐