使用插入排序对字典列表进行排序

时间:2014-03-26 16:27:07

标签: python sorting python-3.x dictionary

此类用于教育目的。不允许构建排序。

如果您认为我的问题和答案有所帮助,请投票给我和第一个回答的人: @ J.F。塞巴斯蒂安

我在SO上发现了这个 - “How to do an insertion sort on a list of dictionaries in python?

但答案似乎不对。

使用上述问题的答案代码会引发此错误:

  

TypeError:list indices必须是整数,而不是dict

示例:

lst = [{'a':20, 'b':30, 'c':25, 'd': 600},{'a':60, 'b':10, 'c':43, 'd': 20}]`

使用插入排序进行排序,例如排序b,我们应该

[{'a':60, 'b':10, 'c':43, 'd': 20},{'a':20, 'b':30, 'c':25, 'd': 600}]

但我的代码

[{'b': 10, 'c': 25, 'a': 20, 'd': 600}, {'b': 30, 'c': 43, 'a': 60, 'd': 20}]

他替换词典列表中的键和值

这是我的代码:

def insertionSort(allData, key):

    for i in range(len(allData)):
        temp = allData[i][key]
        j = i
        while j > 0 and temp < allData[j - 1][key]:
               allData[j][key] = allData[j - 1][key]
               j = j - 1
        allData[j][key] = temp

我的作业排序结果:

{'snow': 19.2, 'minT': -10.8, 'month': 12, 'maxT': 9.0, 'rain': 45.0, 'year': 2003, 'meanT': -0.1, 'yearmonth': 193801}
{'snow': 35.6, 'minT': -20.0, 'month': 1, 'maxT': 8.9, 'rain': 34.3, 'year': 1974, 'meanT': -5.9, 'yearmonth': 193802}
{'snow': 0.0, 'minT': 9.7, 'month': 8, 'maxT': 34.8, 'rain': 20.8, 'year': 2007, 'meanT': 22.4, 'yearmonth': 193803}`

yearmonth进行排序后,他们会将yearmonth从小到大替换,但不会更改字典。

为什么会发生这种情况,以及我如何改变它?

==================================

答案:

在'J.F.的一些基本副本之后塞巴斯蒂安的代码 我发现我无法直接使用代码

sort(a,b)

输出:

  

TypeError:'str'对象不可调用

我应该用     sort(a,b = lambda x:x ['thekey']) 然后,JFS创建了一个新功能,使其工作。

我也找到另一种方式: 只需更改JFS代码行5:

    if key(L[j]) <= key(d):

    if L[j][key] <= d[key]:

然后一切正常! 希望这也可以帮助其他人,以及那些使用谷歌并与我做同样任务的人。

1 个答案:

答案 0 :(得分:0)

尝试编写一个与整数列表一起使用的插入排序过程。然后很容易修改它以接受key参数,以允许任意比较:

def insertion_sort_impl(L, *, key):
    for i in range(1, len(L)): # loop-invariant: `L[:i]` is sorted
        d = L[i]
        for j in range(i - 1, -1, -1): 
            if key(L[j]) <= key(d): 
               break
            L[j + 1] = L[j]
        else: # `key(L[j]) > key(d)` for all `j`
            j -= 1
        L[j + 1] = d

示例:

lst = [{'a':20, 'b':30, 'c':25, 'd': 600},{'a':60, 'b':10, 'c':43, 'd': 20}]
insertion_sort_impl(lst, key=lambda x: x['d']) # sort by `d` key
print(lst)

输出

[{'a': 60, 'c': 43, 'b': 10, 'd': 20}, {'a': 20, 'c': 25, 'b': 30, 'd': 600}]

注意:忽略字典中键的顺序。它可能会在不同的运行中发生变化,但具有较小值的键d的字典将始终位于左侧。

key函数的名称insertion_sort_impl()与字典键无关。它是许多内置函数使用的命名约定; key用于获取用于比较的值:

>>> max([1, 2], key=lambda x: -x)
1
>>> min([1, -2], key=lambda x: x*x)
1
>>> sorted([-1, 0, 1], key=lambda x: x*x-x)
[0, 1, -1]

要理解为什么循环是从1开始的,您可以阅读Insertion sort的一般说明。

如果insertion_sort功能的界面已修复,那么您可以按insertion_sort_impl

来定义
from operator import itemgetter

def insertion_sort(L, key):
    return insertion_sort_impl(L, key=itemgetter(key))