Python 仅当字典键的值没有一定数量的重复项时才选择字典键

Python 仅当字典键的值没有一定数量的重复项时才选择字典键,python,dictionary,Python,Dictionary,给定一个字典和一个新字典中键数的限制,我希望新字典包含具有最高值的键 给定的dict是: dict = {'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1 } 我想得到一个新的字典,其中包含长度限制值最高的键 例如,对于limit=1,新的dict是 {'apple':5} 如果限值=2 {'apple':5, 'pears':4} 我试过这个: return dict(sorted(dictation.items(),key=

给定一个字典和一个新字典中键数的限制,我希望新字典包含具有最高值的键

给定的dict是:

dict = {'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1 }
我想得到一个新的字典,其中包含长度限制值最高的键

例如,对于limit=1,新的dict是

{'apple':5} 
如果限值=2

{'apple':5, 'pears':4}
我试过这个:

return dict(sorted(dictation.items(),key=lambda x: -x[1])[:limit])
但当我尝试极限=3时,我得到

{'apple':5, 'pears':4, 'orange':3}
但它不应该包括橙色:3因为橙色和猕猴桃有相同的优先级,如果我们包括猕猴桃和橙色,它将超过限制,所以它不应该包括两者。我应该回去

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

方法是使用一个集合计数器和最常见的计数器。然后,您可以根据需要再选择一个,并不断弹出,直到最后一个值发生更改:

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}

这在计算上不是很好,但它是有效的。它创建一个对象来获取数据的排序输出,并创建一个保存与分数匹配的列表的倒排对象-它使用两种方法和一些数学方法创建结果:

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
输出:

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}

正如您所注意到的,按top 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}
这里我们假设最大的\u项 这本词典似乎很贵。对于较大的输入,可以使用对分,例如:

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}

我一直在问这个问题,直到你说因为我不能添加橙色。如果我加进去的话,它会超过限额。那么你是说如果有多个项目的数量相同,你应该只在所有项目都符合限额的情况下才接受?你们有并没有调查过最普通的柜台是否能满足你们的需要?我建议不要尝试将它放在一行中。但是OP说,对于limit=3,dict应该仍然有两个键,因为我没有倒立。@timgeb我添加了必要的颠簸。失去了所有的吸引力:比我的还要短
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}