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

时间:2018-10-24 06:57:49

标签: python sorting

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

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

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

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

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

我想自己实现一个插入排序。现在,我的代码如下:

def insertionSort(arr):

    for i in range(1, len(arr)):
        key = d[arr[i]]['rating']
        second_key = d[arr[i]]['hours_worked']
        j = i - 1
        while j >= 0 and key < d[arr[j]]['rating']:
            arr[j+1] = arr[j]
            j -= 1
        d[arr[j+1]]['rating'] = key 

    return arr

我似乎无法使用第二把钥匙进行比较。而且,这根本行不通。有什么帮助吗?

请注意,我无法更改输入法和字典的性质,请使用内置方法无答案。

2 个答案:

答案 0 :(得分:3)

不是您不能使用第二把钥匙进行比较,而是您根本就没有。

而且,模仿它们的形状也很不错(即使您没有使用内置方法也是如此)。

所以我们尝试一下:

def insertionSort(arr, key=lambda x: x):

这表示正常的比较是按元素本身进行的。在排序内部,您基本上可以检查key(element1)并将其与key(element2)进行比较。

如果只想对一些数字进行排序,则默认的key函数就可以了:它将返回相同的数字,以便进行比较。

如果您想使用例如一个名字,你可以做key=lambda person: person.name

如果您有多个条件怎么办?数组和元组有一个有趣的特性:它们是可比的!比较的结果是第一个元素的比较,除非相等,否则将进行下一个元素的比较。因此,(0, 5) < (1, 5) < (1, 7) < (2, 9)。我们怎么使用呢?

 key=lambda e_id: (-d[e_id]['rating'], -d[e_id]['hours_worked'])

此键函数构造一个由负评分和hours_worked(负)组成的元组(因为我们以相反的顺序(从高到低)排序)。排序功能根本不需要更改:您只需要为一个标准实施普通的插入排序:key(element1)是大于,小于还是等于key(element2)

答案 1 :(得分:0)

您应该交换乱序找到的项目,并且在第一个键相等时应该比较第二个键:

def insertionSort(arr):
    for i in range(1, len(arr)):
        key = d[arr[i]]['rating']
        second_key = d[arr[i]]['hours_worked']
        j = i - 1
        while j >= 0 and key > d[arr[j]]['rating'] or key == d[arr[j]]['rating'] and second_key > d[arr[j]]['hours_worked']:
            arr[j+1], arr[j] = arr[j], arr[j+1]
            j -= 1
        d[arr[j+1]]['rating'] = key
    return arr

这样:

insertionSort(arr)

返回:

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