这是我当前的代码
pN ={'dave': 10, 'jacinta': 10, 'james': 8, 'john': 6, 'jack': 3, 'sam': 2}
highestCount = max(pN.values())
for k, v in pN.items():
if v == highestCount:
print(v,k)
然而,这仅打印顶级用户,如果共享该位置,则再次打印
10 dave
10 jacinta
我需要能够打印任意数量的顶级用户(n
),并将其格式化,例如n = 5
:
10 john, jacinta,
8 james
6 john
3 jack
2 sam
答案 0 :(得分:11)
使用collections.defaultdict
,交换 keys
和 values
from collections import defaultdict
dct = defaultdict(list)
for k, v in pN.items():
dct[v].append(k)
# defaultdict(<class 'list'>, {10: ['dave', 'jacinta'], 8: ['james'], 6: ['john'], 3: ['jack'], 2: ['sam']})
使用 sorted
输出:
for k, v in sorted(dct.items(), reverse=True):
print(k, ', '.join(v))
# Result
10 dave, jacinta
8 james
6 john
3 jack
2 sam
function
返回热门 n
用户(将关系视为一个条目):
def top_n(d, n):
dct = defaultdict(list)
for k, v in d.items():
dct[v].append(k)
return sorted(dct.items())[-n:][::-1]
top_n(pN, 3)
# [(10, ['dave', 'jacinta']), (8, ['james']), (6, ['john'])]
defaultdict
简单快捷,以下是一些时间来证明它:将定时的功能
def chris_z(d, n):
dct = defaultdict(list)
for k, v in d.items():
dct[v].append(k)
return sorted(dct.items())[-n:][::-1]
def tim_lombard(score_dict, n):
lot = [(k,v) for k, v in score_dict.items()] #make list of tuple from scores dict
nl = []
while len(lot)> 0:
nl.append(max(lot, key=lambda x: x[1]))
lot.remove(nl[-1])
def ajax(d, n:'n_users', top = True):
_ranks = sorted(d.values())
_ranks = _ranks[-n:] if top else _ranks[:n]
return {i:[a for a, b in d.items() if b == i] for i in _ranks}
<强> 结果 强>
x = [''.join(i) for i in itertools.permutations('chrisz', 6)]
y = [random.randint(0, 100) for _ in range(720)]
z = dict(zip(x, y))
In [40]: %timeit chris_z(z, 500)
110 µs ± 259 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [42]: %timeit tim_lombard(z, 500)
26.2 ms ± 60 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [43]: %timeit ajax(z, 500)
15.3 ms ± 227 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
答案 1 :(得分:1)
您可以使用sorted
和词典理解:
from typing import Dict, List
def ranking(d, n:'n_users', top = True) -> Dict[int, List[str]]:
_ranks = sorted(d.values())
_ranks = _ranks[-n:] if top else _ranks[:n]
return {i:[a for a, b in d.items() if b == i] for i in _ranks}
pN ={'dave': 10, 'jacinta': 10, 'james': 8, 'john': 6, 'jack': 3, 'sam': 2}
for a, b in sorted(ranking(pN, 10).items(), key=lambda x:x[0], reverse=True):
print('{} {}'.format(a, ', '.join(b)))
输出:
10 dave, jacinta
8 james
6 john
3 jack
2 sam
编辑:对于任意数量的顶级用户,将值传递给函数:
_r = ranking(pN, 5) #for the top 5 users
答案 2 :(得分:1)
这对你有用吗?
pN ={'dave': 10, 'jacinta': 10, 'james': 8, 'john': 6, 'jack': 3, 'sam': 2}
def top_n_scores(n, score_dict):
''' returns the n scores from a name:score dict'''
lot = [(k,v) for k, v in pN.items()] #make list of tuple from scores dict
nl = []
while len(lot)> 0:
nl.append(max(lot, key=lambda x: x[1]))
lot.remove(nl[-1])
return nl[0:n]
获得前4名:
top_n_scores(4, pN)
[('dave', 10), ('jacinta', 10), ('james', 8), ('john', 6)]
答案 3 :(得分:0)
您应该使用内置collections.defaultdict
功能的sorted()
进行尝试。
from collections import defaultdict
def sort_it(_dict, n):
result = defaultdict(list)
for name, num in _dict.items():
result[num].append(name)
return sorted(result.items(), reverse=True)[:n]
>>> pN = {'dave': 10, 'jacinta': 10, 'james': 8, 'john': 6, 'jack': 3, 'sam': 2}
>>> top3 = sort_it(pN, 3)
[(10, ['jacinta', 'dave']), (8, ['james']), (6, ['john'])] # Output
答案 4 :(得分:0)
由于您希望按分数分组,因此使用itertools.groupby
:
scores ={'dave': 10, 'jacinta': 10, 'james': 8, 'john': 6, 'jack': 3, 'sam': 2}
from itertools import groupby
from operator import itemgetter
get_score = itemgetter(1)
def group_users_by_score(scores, n=-1):
sorted_users = sorted(scores.items(), key=get_score, reverse=True)
top_n = sorted_users[:n]
return groupby(top_n, key=get_score)
def display_top_users(scores, n=-1):
for score, users in group_users_by_score(scores, n):
print("%3d %s" % (score, ', '.join(u for (u,s) in users)))
举个例子:
>>> display_top_users(scores, 3)
10 dave, jacinta
8 james
>>> display_top_users(scores)
10 dave, jacinta
8 james
6 john
3 jack