【问题标题】:Pythonic sort a list of dictionaries in a tricky orderPythonic 以复杂的顺序对字典列表进行排序
【发布时间】:2015-03-14 02:03:57
【问题描述】:

我有一个按正确顺序排序的 id 列表:

ids = [1, 2, 4, 6, 5, 0, 3]

我还有一个字典列表,以某种随机方式排序:

rez = [{'val': 7, 'id': 1}, {'val': 8, 'id': 2}, {'val': 2, 'id': 3}, {'val': 0, 'id': 4}, {'val': -1, 'id': 5}, {'val': -4, 'id': 6}, {'val': 9, 'id': 0}]

我的意图是以对应于ids 的方式对rez 列表进行排序:

rez = [{'val': 7, 'id': 1}, {'val': 8, 'id': 2}, {'val': 0, 'id': 4}, {'val': -4, 'id': 6}, {'val': -1, 'id': 5}, {'val': 9, 'id': 0}, {'val': 2, 'id': 3}]

我试过了:

rez.sort(key = lambda x: ids.index(x['id']))

但是这种方式对我来说太慢了,因为 len(ids) > 150K,而且每个 dict 实际上都有很多键(有些值是字符串)。任何建议如何以最 Pythonic 但仍然最快的方式做到这一点?

【问题讨论】:

    标签: python list sorting dictionary


    【解决方案1】:

    您不需要sort,因为ids 指定了结果的整个顺序。您只需要通过它们的 id 选择正确的元素:

    rez_dict = {d['id']:d for d in rez}
    rez_ordered = [rez_dict[id] for id in ids]
    

    这给出了:

    >>> rez_ordered
    [{'id': 1, 'val': 7}, {'id': 2, 'val': 8}, {'id': 4, 'val': 0}, {'id': 6, 'val': -4}, {'id': 5, 'val': -1}, {'id': 0, 'val': 9}, {'id': 3, 'val': 2}]
    

    这应该比排序更快,因为它平均可以在线性时间内完成,而排序是 O(nlogn)。

    请注意,这假设每个 id 将有一个条目,如您的示例所示。

    【讨论】:

      【解决方案2】:

      我认为你在正确的轨道上。如果您需要加快速度,因为您的列表太长并且您具有二次复杂度,您可以先将列表转换为字典,将 id 映射到它们各自的索引。

      indices = {id_: pos for pos, id_ in enumerate(ids)}
      rez.sort(key = lambda x: indices[x['id']])
      

      这样,indices{0: 5, 1: 0, 2: 1, 3: 6, 4: 2, 5: 4, 6: 3}rez

      [{'id': 1, 'val': 7}, 
       {'id': 2, 'val': 8}, 
       {'id': 4, 'val': 0}, 
       {'id': 6, 'val': -4}, 
       {'id': 5, 'val': -1}, 
       {'id': 0, 'val': 9}, 
       {'id': 3, 'val': 2}]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-30
        • 2018-10-24
        • 1970-01-01
        • 2021-10-31
        • 1970-01-01
        • 2018-11-27
        • 1970-01-01
        • 2023-04-01
        相关资源
        最近更新 更多