Python没有结果,并且KeyError:1

时间:2018-08-21 22:08:44

标签: python dictionary

def fre(dic, k):
    max_k = dic.keys()[0]
    max_v = dic.values()[0]
    while len(dic2) < k:
        for key, value in dic.items():
            if max_v < value:
                max_k = key
                max_v = value

        dic2[max_k] = max_v
        del dic[max_k]
    return dic2
# dic is a dictionary, k is an int

这个问题是要获取dic中的k个最大值,并获取匹配的key:value对。但是我遇到了运行问题,并遇到了KeyError:1。

1 个答案:

答案 0 :(得分:1)

问题在于,每次循环时,您将max_kmax_v留给刚发现的键值对。

由于这是最大值,因此词典中的其他值都不会更大。因此,在循环结束时,您仍将拥有相同的max_kmax_v。然后,您将尝试再次del dic[max_k],它会引发一个KeyError,因为您已经删除了它。

解决方案很简单:采用将max_kmax_v设置为第一个元素的代码,然后将其移到外部循环中,这样它就每次运行,而不仅仅是第一次运行: / p>

while len(dic2) < k:
    max_k = dic.keys()[0]
    max_v = dic.values()[0]

    for key, value in dic.items():
        if max_v < value:
            max_k = key
            max_v = value

    dic2[max_k] = max_v
    del dic[max_k]

但是,在我们这样做的时候,有更简单的方法(或者至少难于巧妙地弄错了)。

最明显的是只sort the items by value,然后取第一个k

import operator

def fre(dic, k):
    return dict(sorted(dic.items(), key=operator.itemgetter(1), reverse=True)[:k])

有关关键功能的工作原理以及itemgetter的更多信息,请参见Sorting HOWTO

但是您可以提高效率。 sorted显然必须对所有n值进行排序,才能获得最高的k,因此需要O(n)空间和O(n log n)时间。如果kn小很多,可以使用heapq.nlargest来做得更好,{{3}}仅占用O(k)的空间和O(n log k)的时间:

import heapq
import operator

def fre(dic, k):
    return dict(heapq.nlargest(k, dic.items(), key=operator.itemgetter(1)))

无论哪种方式,都不会从dic中删除密钥;如果需要,可以手动进行:

def fre(dic, k):
    dic2 = dict(heapq.nlargest(k, dic.items(), key=operator.itemgetter(1)))
    for key in dic2:
        del dic[key]
    return dic2