Python中字典值的稳定排序

时间:2016-02-17 17:18:38

标签: python sorting dictionary

我是Python的新手,我正在努力解决问题以提高我的编码技能。我正在研究一个问题,我需要stable sort python中的字典。请在下面找到详细信息:

输入:

1 2
16 3
11 2
20 3
3 5
26 4
7 1
22 4

以上输入,我已添加到两个lists k and v

k = ['1', '16', '11', '20', '3', '26', '7', '22']
v = ['2', '3', '2', '3', '5', '4', '1', '4']

我已将这两个列表添加到字典中,以将其作为键值对。我使用了OrderDict,因为我希望元素的顺序与它们在输入中的顺序相同。

from collections import OrderedDict
d = OrderedDict(zip(k, v))

现在,我需要按照与值相反的顺序对字典d进行排序。 (我实际上必须做一个稳定的排序,因为python中的sorted是一个稳定的排序,我已经使用过了。来源:Here)为此:

s = sorted(d, key = itemgetter(1), reverse=True)

预期产出:

 3 5
26 4
22 4
16 3
20 3
1 2
11 2
7 1

但是在我实现了上面的sorted函数之后,我无法获得预期的输出。我得到IndexError: string index out of range

有人可以告诉我,我在哪里做错了。我的方法是错误的还是流程错了?你能否告诉我为什么我无法按预期获得输出。提前致谢。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:6)

这是一种方法:

>>> sorted_kv = sorted(d.items(), key=lambda (k,v):int(v), reverse=True)
>>> OrderedDict(sorted_kv)
OrderedDict([('3', '5'), ('26', '4'), ('22', '4'), ('16', '3'), ...

这将获取字典中的键/值对,对它们进行排序,并创建一个具有所需顺序的新有序字典。

key=的{​​{1}}参数指定要根据第二项的数值对对进行排序。

我需要调用sorted()的原因是你的字典将键和值都保存为字符串。按原样排序它们会起作用,但会生成lexicographic ordering而不是数字。

答案 1 :(得分:4)

您忘记使用.items()(Python3)或.iteritems()(Python2)访问字典中的项目。

此外,您需要导入operator模块才能使用itemgetter()

所以代码看起来像:

import operator
from collections import OrderedDict

k = ['1', '16', '11', '20', '3', '26', '7', '22']
v = ['2', '3', '2', '3', '5', '4', '1', '4']

d = OrderedDict(zip(k, v))

out = sorted(d.items(), key=operator.itemgetter(1), reverse=True)

列表out如下:

[('3', '5'), ('26', '4'), ('22', '4'), ('16', '3'), ('20', '3'), ('1', '2'), ('11', '2'), ('7', '1')]

要进行打印,您可以使用以下方法访问列表中的每个元组:

for i,k in out:
    print(i,k) 

给出了所需的输出:

3 5
26 4
22 4
16 3
20 3
1 2
11 2
7 1

我已经写了一个上面给出的代码示例,可以在ideone.com找到。

答案 2 :(得分:1)

这是另一种方法:

from collections import OrderedDict

k = ['1', '16', '11', '20', '3', '26', '7', '22']
v = ['2', '3', '2', '3', '5', '4', '1', '4']

d = OrderedDict(zip([int(x) for x in k], [int(y) for y in v]))  # convert from string to int
sorted_items = sorted(d.items())
sorted_items.reverse()
s = OrderedDict(sorted_items)  # new sorted ordered dict

答案 3 :(得分:0)

这是我对这项任务的一点思考:

LSL R0, R0, #2
LDR R1, [R4, R0]
ADD R1, R1, #1
STR R1, [R4, R0]

输出:

k = ['1', '16', '11', '20', '3', '26', '7', '22']
v = ['2', '3', '2', '3', '5', '4', '1', '4']

# create a dictionary
d = dict([(k[ind], v[ind]) for ind in range(0, len(k))])

for order in sorted(d, key=d.__getitem__, reverse=True):
    print ("{}: {}".format(order, d[order]))

但我注意到,在您的预期输出中' 1'走在' 11之前。这有什么理由吗?