【问题标题】:Python: How to sort list of dictionaries by value and indexPython:如何按值和索引对字典列表进行排序
【发布时间】:2018-08-10 08:17:38
【问题描述】:

我有一个数据字典列表,在某些地方有序而在其他地方无序:

例如:

data = [{"text":'a', "value":1},
        {"text":'b', "value":1},
        {"text":'j', "value":2},
        {"text":'k', "value":50},
        {"text":'b', "value":50},
        {"text":'y', "value":52},
        {"text":'x', "value":2},
        {"text":'k', "value":3},
        {"text":'m', "value":3}]

我想将它们排序为:

 o = [{"text":'a', "value":1},
      {"text":'b', "value":1},
      {"text":'j', "value":2},
      {"text":'x', "value":2},
      {"text":'k', "value":3},
      {"text":'m', "value":3},
      {"text":'k', "value":50},
      {"text":'b', "value":50},
      {"text":'y', "value":52}]

其中我的排序是项目索引和第二个值的某种组合,我正在考虑排序:

key=[(2nd value)<<len(closest power of 2 to len(index)) + index]

我可以按第二个值对字典列表进行排序:

data.sort(key= lambda x:x['value'])

我还要如何添加字典的索引?

我可以使用更好的排序键吗?

【问题讨论】:

    标签: python sorting


    【解决方案1】:

    您似乎正在寻找 text 字段作为辅助排序键。最简单的方法是简单地按优先级顺序使用元组作为键:

    sorted(data, key=lambda x: (x['value'], x['text']) ) 
    

    这能满足您的需要吗?输出:

    [{'text': 'a', 'value': 1}, {'text': 'b', 'value': 1}, {'text': 'j', 'value': 2}, {'text': 'x', 'value': 2}, {'text': 'k', 'value': 3}, {'text': 'm', 'value': 3}, {'text': 'b', 'value': 50}, {'text': 'k', 'value': 50}, {'text': 'y', 'value': 52}]
    

    值 (k, 50) 和 (b, 50) 现在是另一个顺序;我希望我正确地读懂了你的想法。


    根据 OP 说明更新

    我检查了文档。 Python 的sort 方法是稳定的,所以你根本不需要第二个排序键:如果出现平局,sort 将保持原来的顺序:

    >>> data.sort(key= lambda x:x['value'])
    >>> data
    [{'text': 'a', 'value': 1}, {'text': 'b', 'value': 1}, {'text': 'j', 'value': 2}, {'text': 'x', 'value': 2}, {'text': 'k', 'value': 3}, {'text': 'm', 'value': 3}, {'text': 'k', 'value': 50}, {'text': 'b', 'value': 50}, {'text': 'y', 'value': 52}]
    

    ...这就是你所要求的。

    【讨论】:

    • 我不是在寻找文本字段作为辅助排序键,我正在寻找列表中项目的列表索引作为辅助排序键
    • 啊。在这种情况下,您只需要任何 stable 排序。检查文档以查看哪些将保留原始订单,以防出现平局。我相信sorted 已经这样做了。
    【解决方案2】:

    使用enumerate 获取索引并使用它进行排序

    >>> res = [d for i,d in sorted(enumerate(data), key=lambda i_d: (i_d[1]['value'], i_d[0]))]
    >>> pprint(res)
    [{'text': 'a', 'value': 1},
     {'text': 'b', 'value': 1},
     {'text': 'j', 'value': 2},
     {'text': 'x', 'value': 2},
     {'text': 'k', 'value': 3},
     {'text': 'm', 'value': 3},
     {'text': 'k', 'value': 50},
     {'text': 'b', 'value': 50},
     {'text': 'y', 'value': 52}]
    

    要就地排序,您可以尝试使用itertools.count

    >>> from itertools import count
    >>> cnt=count()
    >>> data.sort(key=lambda d: (d['value'], next(cnt)))
    >>> pprint(data)
    [{'text': 'a', 'value': 1},
     {'text': 'b', 'value': 1},
     {'text': 'j', 'value': 2},
     {'text': 'x', 'value': 2},
     {'text': 'k', 'value': 3},
     {'text': 'm', 'value': 3},
     {'text': 'k', 'value': 50},
     {'text': 'b', 'value': 50},
     {'text': 'y', 'value': 52}]
    >>> 
    

    【讨论】:

    • 这行得通。有没有办法用排序而不是排序(不想使用更多内存)。
    • @azazelspeaks。更新了答案
    【解决方案3】:

    你试过了吗:

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

    【讨论】:

    • 这就是我所说的我已经尝试过的。排序和排序都排序。我正在寻找按两个键排序。
    猜你喜欢
    • 1970-01-01
    • 2021-08-25
    • 2011-02-22
    • 2013-04-11
    • 2010-09-09
    相关资源
    最近更新 更多