【问题标题】:Sorting a dictionary of lists对列表字典进行排序
【发布时间】:2021-03-19 14:09:34
【问题描述】:

我有以下字典:

my_dict = {"user": [1, 2, 3, 4], "sex": ['M', 'F', 'O', 'F'],"timeOfArrival": [4, 1, 3, 8]}

我想找到一种基于timeOfArrival 键对其进行排序的方法,例如以下示例:

my_dict = {"user": [2,3,1,4 ], "sex": ['F', 'O', 'M', 'F' ],"timeOfArrival": [4, 1, 3, 8]}

现在我很难想出一个直截了当的解决方案。

我尝试对timeOfArrival 进行排序,然后我尝试在my_dict 内循环,这样我就可以将值重新排列到它们的“正确”位置,这可行,但如果我有重复的值(即@987654327 @) 我得到了一本比我一开始给的更大的字典。

有没有更好的方法来对我的字典进行排序?

def sortDict(dictionary={},name="test"):
  sortedList=sorted(my_dict[name])
  dictKeys=list(dictionary.keys())
  testDict={}
  for i in dictKeys:
    testDict[i]=[]
  for key in dictKeys:
    for item in sortedList:
      for pos in range(0,len(dictionary[name])):
        if(item==dictionary[name][pos]):
          testDict[key].append(dictionary[key][pos])
  return testDict

【问题讨论】:

  • 这能回答你的问题吗? Sorting list based on values from another list
  • 这个问题与排序字典无关。这是关于排序和同步多个列表。
  • @jarmod 显然我没有正确解释我的问题。我不需要对多个列表进行排序,我需要根据其中一个列表对字典进行排序。同步比重新定位需要更多时间
  • @MauriceMeyer 我会尝试实现它并回来与您分享结果
  • @MauriceMeyer 它有效,谢谢。

标签: python sorting dictionary


【解决方案1】:

我想这就是你要找的。它通过获取已排序到达时间的索引来确定排序顺序。然后我使用索引顺序对字典中的所有列表进行排序。

order = [i for i, _ in sorted(enumerate(my_dict['timeOfArrival']), key=lambda x: x[1])]
for key, value in my_dict.items():
    if key != 'timeOfArrival': # Expected output shows timeOfArrival should not be sorted
        my_dict[key] = [value[i] for i in order]

【讨论】:

  • 您可能希望在for 循环中添加if key != 'timeOfArrival':
  • 到达时间在for循环之前的字典中没有排序。
  • 这是正确的,它们不应该在之后进行排序。查看问题和预期输出。
  • 你是对的。我会仔细检查一下这是故意的还是错误的。
【解决方案2】:

数据可以与zip合并。

my_dict = {
    "user": [1, 2, 3, 4],
    "sex": ['M', 'F', 'O', 'F'],
    "timeOfArrival": [4, 1, 3, 8]}

print(list(zip(my_dict['timeOfArrival'], my_dict['user'], my_dict['sex'])))

这会给你

[(4, 1, 'M'), (1, 2, 'F'), (3, 3, 'O'), (8, 4, 'F')]

这可以排序。

data = list(sorted(zip(my_dict['timeOfArrival'], my_dict['user'], my_dict['sex'])))
print(data)

结果:

[(1, 2, 'F'), (3, 3, 'O'), (4, 1, 'M'), (8, 4, 'F')]

解包排序后的数据:

data = list(zip(*data))

现在data 看起来像这样:

[(1, 3, 4, 8), (2, 3, 1, 4), ('F', 'O', 'M', 'F')]

最后必须将排序后的数据放回匹配的字典条目中

my_dict['user'] = list(data[1])
my_dict['sex'] = list(data[2])

现在my_dict包含{'user': [2, 3, 1, 4], 'sex': ['F', 'O', 'M', 'F'], 'timeOfArrival': [4, 1, 3, 8]}


压缩版

my_dict = {
    "user": [1, 2, 3, 4],
    "sex": ['M', 'F', 'O', 'F'],
    "timeOfArrival": [4, 1, 3, 8]}

data = list(zip(*sorted(zip(my_dict['timeOfArrival'], my_dict['user'], my_dict['sex']))))
my_dict['user'] = list(data[1])
my_dict['sex'] = list(data[2])

【讨论】:

    【解决方案3】:

    我建议你使用“Insertion Sort”算法。

    我对其进行了修改以适应您的示例,它似乎可以按照您的意愿执行:

    
    my_dict = {"user": [2,3,1,4 ], "sex": ['F', 'O', 'M', 'F' ],"timeOfArrival": [4, 1, 3, 8]}
    
    def insertion_sort(my_dict):
        for k in range(1, len(my_dict['timeOfArrival'])):
    
            cur_timeOfArrival = my_dict['timeOfArrival'][k]
            cur_sex = my_dict['sex'][k]
            cur_user = my_dict['user'][k]
            j=k
    
            while j > 0 and my_dict['timeOfArrival'][j-1] > cur_timeOfArrival:
                my_dict['timeOfArrival'][j] = my_dict['timeOfArrival'][j-1]
                my_dict['sex'][j] = my_dict['sex'][j-1]
                my_dict['user'][j] = my_dict['user'][j-1]
                j -= 1
    
            my_dict['timeOfArrival'][j] = cur_timeOfArrival
            my_dict['sex'][j] = cur_sex
            my_dict['user'][j] = cur_user
    
        return my_dict
    
    print(insertion_sort(my_dict))
    #{'user': [3, 1, 2, 4], 'sex': ['O', 'M', 'F', 'F'], 'timeOfArrival': [1, 3, 4, 8]}
    

    问候。

    【讨论】:

      【解决方案4】:

      事情是我只需要对我的字典进行排序并将我的列表彼此分开,所以像这样组合列表:

      [(4, 1, 'M'), (1, 2, 'F'), (3, 3, 'O'), (8, 4, 'F')]

      是不可能的。

      感谢大家的宝贵时间,更重要的是,感谢@MauriceMeyer,我得到了它的工作。

      def sortDict(dictionary={},name="test"):
        sortedList=sorted(my_dict[name])
        dictKeys=list(dictionary.keys())
        testDict={}
        for key in dictKeys:
          testDict[key]=[x for _,x in sorted(zip(my_dict[name],my_dict[key]))]
        return testDict
      

      【讨论】:

      • 真正值得理解的是,您不是在对字典进行排序。
      【解决方案5】:

      你需要压缩然后排序:

      # your unsorted dictionary
      my_dict = {"user": [1, 2, 3, 4], "sex": ['M', 'F', 'O', 'F'],"timeOfArrival": [4, 1, 3, 8]}
      
      # your sorted dictionary
      sorted_dict = {}
      
      # zip lists, sort by timeOfArrival and unpack into the new dictionary
      sorted_dict["user"], sorted_dict["sex"], sorted_dict["timeOfArrival"] = zip(*sorted(zip(my_dict["timeOfArrival"], my_dict["user"], my_dict["sex"])))
      
      # convert the tuples in the new dictionary into a list
      sorted_dict["user"] = list(sorted_dict["user"])
      sorted_dict["sex"] = list(sorted_dict["sex"])
      sorted_dict["timeOfArrival"] = list(sorted_dict["timeOfArrival"])
      
      # you're done ;-)
      print(sorted_dict)
      # {'user': [1, 3, 4, 8], 'sex': [2, 3, 1, 4], 'timeOfArrival': ['F', 'O', 'M', 'F']}
      

      然后用这些新排序的列表重建你的字典。

      【讨论】:

      • 我举了一个例子。这个想法很可靠,但我需要找到一种方法来对字典进行排序而不改变我的答案。
      猜你喜欢
      • 2014-02-14
      • 1970-01-01
      • 1970-01-01
      • 2011-02-22
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      相关资源
      最近更新 更多