代码之家  ›  专栏  ›  技术社区  ›  LBaelish

python高效的字典中的并行列表排序

  •  2
  • LBaelish  · 技术社区  · 6 年前

    标题基本上说明了一切,我正在寻找一个有效的平行列表字典排序。

    unsorted_my_dict = {
       'key_one': [1,6,2,3],
       'key_two': [4,1,9,7],
       'key_three': [1,2,4,3],
       ...
    }
    sorted_my_dict = {
       'key_one': [1,6,3,2],
       'key_two': [4,1,7,9],
       'key_three': [1,2,3,4],
       ...
    }
    

    我想分类 key_three 和字典中的所有其他列表并行。有几个类似的问题,但我正在努力,因为我在字典中有未知数量的键要排序,而且我只知道要排序的键的名称。( 密钥3 )

    希望用普通的Python来实现这一点,不依赖第三方。

    编辑1: 并行是什么意思?我的意思是如果我排序 密钥3 ,这需要交换最后两个值,字典中的所有其他列表也将交换最后两个值。

    编辑2:python 3.4

    3 回复  |  直到 6 年前
        1
  •  5
  •   Olivier Melançon iacob    6 年前

    你可以先分类 enumerate 以恢复所需的索引顺序,然后按该顺序重新排列每个列表。

    my_dict = {
       'key_one': [1,6,2,3],
       'key_two': [4,1,9,7],
       'key_three': [1,2,4,3],
    }
    
    
    def parallel_sort(d, key):
        index_order = [i for i, _ in sorted(enumerate(d[key]), key=lambda x: x[1])]
        return {k: [v[i] for i in index_order] for k, v in d.items()}
    
    print(parallel_sort(my_dict, 'key_three'))
    

    产量

    {'key_one': [1, 6, 3, 2],
     'key_two': [4, 1, 7, 9],
     'key_three': [1, 2, 3, 4]}
    
        2
  •  1
  •   ShadowRanger    6 年前

    zip 将键放在一起,根据相关项对键函数进行排序,然后 拉链 再次恢复原始表单:

    sorted_value_groups = sorted(zip(*unsorted_my_dict.values()), key=lambda _, it=iter(unsorted_my_dict['key_three']): next(it))
    sorted_values = zip(*sorted_value_groups)
    sorted_my_dict = {k: list(newvals) for k, newvals in zip(unsorted_my_dict, sorted_values)}
    

    一点也不干净,我主要是为了好玩才贴的。一个班轮是:

    sorted_my_dict = {k: list(newvals) for k, newvals in zip(unsorted_my_dict, zip(*sorted(zip(*unsorted_my_dict.values()), key=lambda _, it=iter(unsorted_my_dict['key_three']): next(it))))}
    

    这是因为,当 dict 迭代顺序不保证在3.7之前,对于未修改的订单,该顺序保证可重复。 双关语 . 同样, key 函数从开始到结束都是按顺序执行的,所以通过重复迭代来提取键是安全的。我们只需分离所有值,按索引对它们进行分组,按索引键对组进行排序,按键对它们进行重新分组,然后将它们重新附加到原始键上。

    输出完全按照要求进行(原始键的顺序保留在cpython 3.6或任何python 3.7或更高版本上):

    sorted_my_dict = {
       'key_one': [1,6,3,2],
       'key_two': [4,1,7,9],
       'key_three': [1,2,3,4]
    }
    
        3
  •  1
  •   mayurmadnani    6 年前

    首先,使用指定的键进行排序,您可以获得索引顺序。你按顺序重新排列字典中剩下的列表。

    unsorted_my_dict = {
    'key_one': [1, 6, 2, 3],
    'key_two': [4, 1, 9, 7],
    'key_three': [1, 2, 4, 3],
    }
    
    
    def sort_parallel_by_key(my_dict, key):
        def sort_by_indices(idx_seq):
            return {k: [v[i] for i in idx_seq] for k, v in my_dict.items()}
    
        indexes = [idx for idx, _ in sorted(enumerate(my_dict[key]), key=lambda foo: foo[1])]
        return sort_by_indices(indexes)
    
    
    print(sort_parallel_by_key(unsorted_my_dict, 'key_three'))