Python 如何将字典排序为仅从最高值输出?
txt将包含如下内容:Python 如何将字典排序为仅从最高值输出?,python,sorting,dictionary,Python,Sorting,Dictionary,txt将包含如下内容: Matt Scored: 10 Jimmy Scored: 3 James Scored: 9 Jimmy Scored: 8 .... 到目前为止,我的代码是: from collections import OrderedDict #opens the class file in order to create a dictionary dictionary = {} #splits the data so the name is the key while
Matt Scored: 10
Jimmy Scored: 3
James Scored: 9
Jimmy Scored: 8
....
到目前为止,我的代码是:
from collections import OrderedDict
#opens the class file in order to create a dictionary
dictionary = {}
#splits the data so the name is the key while the score is the value
f = open('ClassA.txt', 'r')
d = {}
for line in f:
firstpart, secondpart = line.strip().split(':')
dictionary[firstpart.strip()] = secondpart.strip()
columns = line.split(": ")
letters = columns[0]
numbers = columns[1].strip()
if d.get(letters):
d[letters].append(numbers)
else:
d[letters] = list(numbers)
#sorts the dictionary so it has a alphabetical order
sorted_dict = OrderedDict(
sorted((key, list(sorted(vals, reverse=True)))
for key, vals in d.items()))
print (sorted_dict)
此代码已经生成按字母顺序排序的名称输出,其分数从最高到最低。然而,现在我需要能够以一种方式输出排序的名称,最高分数是第一名,最低分数是最后一名。我尝试使用
max
函数,但是它只输出名称,而不输出分数本身,而且我希望输出的分数仅为最高,而不是像当前代码那样的先前分数。我认为在这种情况下您不需要字典。只需将分数作为元组列表保存即可
即按名称排序:
>>> sorted([('c', 10), ('b', 16), ('a', 5)],
key = lambda row: row[0])
[('a', 5), ('b', 16), ('c', 10)]
或按分数:
>>> sorted([('c', 10), ('b', 16), ('a', 5)],
key = lambda row: row[1])
[('a', 5), ('c', 10), ('b', 16)]
您可以使用
itertools.groupby
单独分离每个键。这个大而长的dict comp很难看,但它的工作原理是对输入进行排序,按冒号前的部分进行分组,然后获取最大的结果并用组名保存
import itertools, operator
text = """Matt Scored: 10
Jimmy Scored: 3
James Scored: 9
Jimmy Scored: 8"""
result_dict = {group:max(map(lambda s: int(s.split(":")[1]), vals)) for
group,vals in itertools.groupby(sorted(text.splitlines()),
lambda s: s.split(":")[0])}
sorted_dict = sorted(result_dict.items(), key=operator.itemgetter(1), reverse=True)
# result:
[('Matt Scored', 10), ('James Scored', 9), ('Jimmy Scored', 8)]
展开dict comp会得到如下结果:
sorted_txt = sorted(text.splitlines())
groups = itertools.groupby(sorted_txt, lambda s: s.split(":")[0])
result_dict = {}
for group, values in groups:
# group is the first half of the line
result_dict[group] = -1
# some arbitrary small number
for value in values:
#value is the whole line, so....
value = value.split(":")[1]
value = int(value)
result_dict[group] = max(result_dict[group], value)
我会从一开始就使用来获得一个排序列表,每当你插入一个新分数时,那么这只是一个反转或获得所需输出的问题:
from bisect import insort
from StringIO import StringIO
d = {}
f = '''Matt Scored: 10
Jimmy Scored: 3
James Scored: 9
Jimmy Scored: 8'''
for line in StringIO(f):
line = line.strip().split(' Scored: ')
name, score = line[0], int(line[1])
if d.get(name):
# whenever new score is inserted, it's sorted from low > high
insort(d[name], score)
else:
d[name] = [score]
d
{'James': [9], 'Jimmy': [3, 8], 'Matt': [10]}
for k in sorted(d.keys()):
# score from largest to smallest, sorted by names
print 'sorted name, high>low score ', k, d[k][::-1]
# highest score, sorted by name
print 'sorted name, highest score ', k, d[k][-1]
然后,要获得所需的输出:
from bisect import insort
from StringIO import StringIO
d = {}
f = '''Matt Scored: 10
Jimmy Scored: 3
James Scored: 9
Jimmy Scored: 8'''
for line in StringIO(f):
line = line.strip().split(' Scored: ')
name, score = line[0], int(line[1])
if d.get(name):
# whenever new score is inserted, it's sorted from low > high
insort(d[name], score)
else:
d[name] = [score]
d
{'James': [9], 'Jimmy': [3, 8], 'Matt': [10]}
for k in sorted(d.keys()):
# score from largest to smallest, sorted by names
print 'sorted name, high>low score ', k, d[k][::-1]
# highest score, sorted by name
print 'sorted name, highest score ', k, d[k][-1]
结果:
sorted name, high>low score James [9]
sorted name, highest score James 9
sorted name, high>low score Jimmy [8, 3]
sorted name, highest score Jimmy 8
sorted name, high>low score Matt [10]
sorted name, highest score Matt 10
作为旁注:
列表[:-1]
==反向列表,列表[-1]
==最后一个元素您的代码可以使用defaultdict
from collections import defaultdict
d = defaultdict(list)
接下来,在处理文件时使用open
上下文管理器是一种很好的做法
with open('ClassA.txt') as f:
最后,当在f
行中循环时,应该使用一个字典,而不是两个。为了便于按分数排序,您需要将分数存储为int
for line in f:
name, score = line.split(':')
d[name.strip()].append(int(score.strip()))
这种方法的一个副作用是,在创建新列表时,具有多个数字的分数(例如,Jimmy Scored:10
)将保持其值(10
)。在原始版本中,list('10')
产生list['1','0']
您可以使用sorted
的key
参数按d
中的值排序,而不是按其键排序
sorted(d, key=lambda x: max(d[x]))
把这一切放在一起,我们得到了
from collections import defaultdict
d = defaultdict(list)
with open('ClassA.txt') as f:
for line in f:
name, score = line.split(':')
d[name.strip()].append(int(score.strip()))
# Original
print(sorted(d.items()))
# By score ascending
print(sorted(d.items(), key=lambda x: max(x[1])))
# By score descending
print(sorted(d.items(), key=lambda x: max(x[1]), reverse=True))
使用
itertools.groupby应该相当容易。让我做点什么up@user3809875不,您误解了这个问题。在这些情况下,您应该使用操作符.itemgetter
,而不是编写自己的匿名函数