仅当字典键的值没有重复的次数时才选择

时间:2018-11-21 18:43:43

标签: python dictionary

鉴于字典以及新字典中键数的限制,我希望新字典包含具有最高值的键。

给定的字典是:

dict = {'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1 }

我想得到一个新的字典,其中的键的长度限制最大。

例如对于limit = 1,新字典是

{'apple':5} 

如果limit = 2

{'apple':5, 'pears':4}

我尝试过:

return dict(sorted(dictation.items(),key=lambda x: -x[1])[:limit])

但是当我尝试limit = 3时,我得到了

{'apple':5, 'pears':4, 'orange':3}

但是它不应该包含橙色:3 因为橙色和猕猴桃具有相同的优先级,如果我们包含猕猴桃和橙色,它将超出限制,因此不应同时包含两者。我应该回来

{'apple':5, 'pears':4}

3 个答案:

答案 0 :(得分:2)

方法是使用collections.Countermost_common(n)。然后,您可以根据需要再添加一个并继续弹出,直到最后一个值更改为止:

from collections import Counter

dct = {'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1}
n = 3

items = Counter(dictation).most_common(n+1)
last_val = items[-1][1]
if len(items) > n:
    while items[-1][1] == last_val:
        items.pop()

new = dict(items)
# {'apple': 5, 'pears': 4}

答案 1 :(得分:1)

这在计算上不是很好,但是可以。它创建一个Counter对象以获取数据的排序输出,并创建一个倒置的defaultdict来保存与分数匹配的列表-它同时使用一些数学运算来创建结果:

from collections import defaultdict, Counter

def gimme(d,n):
    c = Counter(d)
    grpd = defaultdict(list)
    for key,value in c.items():
        grpd[value].append(key)


    result = {}
    for key,value in c.most_common():
        if len(grpd[value])+len(result) <= n:
            result.update( {k:value for k in grpd[value] } )
        else:
            break
    return result

测试:

data = {'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1 }

for k in range(10):
    print(k, gimme(data,k))

输出:

0 {}
1 {'apple': 5}
2 {'apple': 5, 'pears': 4}
3 {'apple': 5, 'pears': 4}
4 {'apple': 5, 'pears': 4, 'orange': 3, 'kiwi': 3}
5 {'apple': 5, 'pears': 4, 'orange': 3, 'kiwi': 3}
6 {'apple': 5, 'pears': 4, 'orange': 3, 'kiwi': 3, 'banana': 1}
7 {'apple': 5, 'pears': 4, 'orange': 3, 'kiwi': 3, 'banana': 1}
8 {'apple': 5, 'pears': 4, 'orange': 3, 'kiwi': 3, 'banana': 1}
9 {'apple': 5, 'pears': 4, 'orange': 3, 'kiwi': 3, 'banana': 1}

答案 2 :(得分:1)

请注意,默认情况下,按顶部 n 进行过滤不会排除所有超过指定上限的相等值。这是设计使然。

诀窍是考虑(n + 1)的最高值,并确保字典中的值均高于该数字:

from heapq import nlargest

dictation = {'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1}

n = 3
largest_items = nlargest(n+1, dictation.items(), key=lambda x: x[1])
n_plus_one_value = largest_items[-1][1]

res = {k: v for k, v in largest_items if v > n_plus_one_value}

print(res)

{'apple': 5, 'pears': 4}

我们在这里假设len(largest_items) < n,否则您可以将输入字典作为结果。


字典理解似乎很昂贵。对于较大的输入,可以使用bisect,例如:

from heapq import nlargest
from operator import itemgetter
from bisect import bisect

dictation = {'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1}

n = 3
largest_items = nlargest(n+1, dictation.items(), key=lambda x: x[1])
n_plus_one_value = largest_items[-1][1]

index = bisect(list(map(itemgetter(1), largest_items))[::-1], n_plus_one_value)

res = dict(largest_items[:len(largest_items) - index])

print(res)

{'apple': 5, 'pears': 4}