如何使用2个条件属性对python列表进行排序

时间:2018-10-24 06:26:59

标签: python sorting

让我们说我想对看起来像这样的列表进行排序:

arr = ['45621', '78124', '24613']

上面的列表存储了公司中各个员工的ID。我不想仅根据ID进行排序,而是使用以下字典基于与ID对应的属性进行排序:

employees = {
    '45621' : { 'rating' : 3, 'hours_worked' : 42 },
    '78124' : { 'rating' : 4, 'hours_worked' : 78 },
    '24613' : { 'rating' : 3, 'hours_worked' : 51 }
}

因此,它是这样的:如果员工的rating较高,则其ID将排在第一位。但是,如果有2名员工具有相同的rating,则我们比较hours_worked,而工作更多的人将排在其他人之前。

现在,我正在考虑2种不同的排序方法:插入和合并。我从网络上编辑了一些代码示例,但是我正在努力比较第二个条件,即算法的2个评分相等。例如,我的插入排序的编辑版本如下:

InsertionSort

def insertionSort(arr):
    for i in range(1, len(arr)): 
        key = employees[ arr[i] ]['rating']
        j = i-1
        # Falls apart after this part
        while j >=0 and key < arr[j] : 
            arr[j+1] = arr[j] 
            j -= 1
        arr[j+1] = key 

合并排序似乎更加复杂,但是我试图至少理解一个问题。

任何有关这些排序方法的帮助将不胜感激。谢谢。

注意:我不想使用内置的排序机制,因为这主要是为了学习,所以不是重复的。

3 个答案:

答案 0 :(得分:3)

您可以基于自定义键使用python list.sortsorted

arr = ['45621', '78124', '24613']

employees = {
    '45621' : { 'rating' : 3, 'hours_worked' : 42 },
    '78124' : { 'rating' : 4, 'hours_worked' : 78 },
    '24613' : { 'rating' : 3, 'hours_worked' : 51 }
}

arr.sort(key=lambda x: (employees[x]["rating"], employees[x]["hours_worked"]))
print(arr)

结果:

['45621', '24613', '78124']

此外,由于您首先需要价格更高的轮胎,因此您应该颠倒顺序。

arr.sort(key=lambda x: (employees[x]["rating"], employees[x]["hours_worked"]), reverse=True)

您在这里有一个live example

答案 1 :(得分:0)

首先,我认为将数据组织到一个列表中更好,因为您不需要其中的两个。像这样:

employees = [
    {'user_id': '45621', 'rating' : 3, 'hours_worked' : 42 },
    {'user_id': '78124', 'rating' : 4, 'hours_worked' : 78 },
    {'user_id': '24613', 'rating' : 3, 'hours_worked' : 51 }]

之后,您可以使用列表的内置sort功能,将operator.itemgetter与所需的相应键组合两次。

比方说,您将rating的价值胜过hours_worked,则需要首先按次要的键排序。 reverse=False将高价值放在首位。

这样可以为您提供更多控制权,因为有时并非两种排序都以相同的顺序进行。即:您想将rating降序排序,但hours_worked升序排序(用户评分高,但工作量少,意味着效率更高)

import operator
employees.sort(key=operator.itemgetter('hours_worked'), reverse=True)
employees.sort(key=operator.itemgetter('rating'), reverse=True)

结果:

[{'user_id': '78124', 'rating': 4, 'hours_worked': 78},
 {'user_id': '24613', 'rating': 3, 'hours_worked': 51},
 {'user_id': '45621', 'rating': 3, 'hours_worked': 42}]

排序后,您可以按列表理解顺序依次获取id

[u['user_id'] for u in employees]

哪个给:

['78124', '24613', '45621']

答案 2 :(得分:0)

sorted

arr=sorted(arr,key=lambda x: (employees[x]["rating"], employees[x]["hours_worked"]))

如果需要从高到低排序:

arr=sorted(arr,key=lambda x: (employees[x]["rating"], employees[x]["hours_worked"]), reverse=True)