我一直在谷歌搜索和搜索,我只是找不到答案。
我有一个词典,其中包含群组中的人员以及群组的分数groups = {"john,alfred,willis":5, "james,connor":5}, ...
。然而,人们可以同时分成两组。我想用这本词典做的是根据人数和他们的分数来排序。例如:
>>> groups = {"a,b,c":5, "d,e":6, "f,g,h,i":5, "j,k,l":6, "m,n":10, "a,d,f":5}
我需要按分数排序,然后按人数排序,然后按字母顺序排序作为最终的打破平局。没有重复的组,但是一个组可能拥有"a,b,c,d"
而另一个组可能拥有"a,b,c,e"
。较高的分数胜过较低的分数,更多的人胜过较少的人,字母顺序是......字母顺序。
>>> print(mySort(groups))
"m,n", 10
"j,k,l", 6
"d,e", 6
"f,g,h,i", 5
"a,b,c", 5
"a,d,f", 5
输出格式不一定非如此,但最好是以字典的方式格式化。
我尝试了几种不同的方法,包括按,
分割密钥,因为名称可以是任意长度,但因为Python不是我的第一语言,所以我&#39我觉得很难。
如何按值和字符大小对字典进行排序?
编辑:我在问题中添加了另一部分,我认为我可以不用。事实证明它需要......
答案 0 :(得分:3)
使用sorted
:( key
函数的返回值用于比较)
>>> groups = {"a,b,c":5, "d,e":6, "f,g,h,i":5, "j,k,l":6, "m,n":10}
>>> sorted_keys = sorted(groups, key=lambda k: (groups[k], k), reverse=True)
>>> sorted_keys
['m,n', 'j,k,l', 'd,e', 'f,g,h,i', 'a,b,c']
>>> [(key, groups[key]) for key in sorted_keys]
[('m,n', 10), ('j,k,l', 6), ('d,e', 6), ('f,g,h,i', 5), ('a,b,c', 5)]
<强>更新强>
key
功能应更改如下,以正确计算人数。
lambda k: (groups[k], len(k.split(','))), reverse=True)
答案 1 :(得分:2)
groups = {"a,b,c":5, "d,e":6, "f,g,h,i":5, "j,k,l":6, "m,n":10}
s = sorted(groups.items(),key=lambda x: (x[1],len(x[0])),reverse=True)
for k,v in s:
print (k,v)
m,n 10
j,k,l 6
d,e 6
f,g,h,i 5
a,b,c 5
使用-max(map(ord,x[0])))
按字母表中最新的字母排序,即a,b,c,y
节拍a,b,c,z
。
In [37]: groups = {"a,b,c":5, "d,e":6, "f,g,h,i":5, "j,k,l":6, "m,n":10,"a,b,c,d":12,"a,b,c,e":12,"a,b,c,z":13,"a,b,c,y":13}
In [38]: sorted(groups.items(),key=lambda x: (x[1],len(x[0]),-max(map(ord,x[0].split(","))),reverse=True)
Out[38]:
[('a,b,c,y', 13),
('a,b,c,z', 13),
('a,b,c,d', 12),
('a,b,c,e', 12),
('m,n', 10),
('j,k,l', 6),
('d,e', 6),
('f,g,h,i', 5),
('a,b,c', 5)]
我们使用lambda x: (x[1],len(x[0]),-max(map(ord,x[0].split(","))))
对上面的输出进行排序。
在x[1],len(x[0])
中,我们首先对值x[1]
进行排序,然后对每个键len(x[0])
的长度进行排序。
如果我们与这两者相关联,我们转到-max(map(ord,x[0].split(","))
,以下是一个如何运作的示例:
如果我们将"a,b,c,z" and "a,b,c,y"
作为示例并将其放入列表keys =["a,b,c,z","a,b,c,y"]
中:
首先获得每个char的ords:
In [54]: ords = [list(map(ord,x.split(","))) for x in keys] # get ord values from each char
In [55]: ords
Out[55]: [[97, 98, 99, 122], [97, 98, 99, 121]]
我们正在从最高到最低排序,因此我们使用reverse = True
。
In [56]: sorted([max(x) for x in ords], reverse=True) # puts "z" first because of reversing
Out[56]: [122, 121]
因此我们使用-max(x)
来反转该输出:
In [57]: sorted([-max(x) for x in ords], reverse=True) # now "y" comes first
Out[57]: [-121, -122]
x
中的{p> lambda
是groups.items()
中的每个子项,如下所示:
([('a,b,c', 5), ('a,b,c,d', 12), ('j,k,l', 6), ('d,e', 6), ('a,b,c,z', 13), ('m,n', 10), ('a,b,c,y', 13), ('a,b,c,e', 12), ('f,g,h,i', 5)])
因此,如果我们采用('a,b,c', 5)
x[0] = "a,b,c"
和x[1] = 5
。
答案 2 :(得分:1)
按“人数”排序,你需要
>>> sorted(groups.items(), key=lambda p: (p[1], p[0].count(',')), reverse=True)
[('m,n', 10), ('j,k,l', 6), ('d,e', 6), ('f,g,h,i', 5), ('a,b,c', 5)]
作为旁注,逗号分隔的字符串不是表示事物组的最佳方式。考虑改为将你的dict元组编入索引:
>>> good_groups = {tuple(k.split(',')):v for k, v in groups.items()}
然后
>>> sorted(good_groups.items(), key=lambda p: (p[1], len(p[0])), reverse=True)
[(('m', 'n'), 10), (('j', 'k', 'l'), 6), (('d', 'e'), 6), (('f', 'g', 'h', 'i'), 5), (('a', 'b', 'c'), 5)]
如果您的组将要变异并且应该是列表而不是元组,则不能将它们用作dict键。考虑一个不同的数据结构,例如,一个dicts列表:
groups = [
{ 'members': ['foo', 'bar'], 'score': 5 },
{ 'members': ['baz', 'spam'], 'score': 15 },
etc