python字典值排序

Posted

技术标签:

【中文标题】python字典值排序【英文标题】:python dictionary values sorting 【发布时间】:2011-08-28 02:40:58 【问题描述】:

我有 2 个字典,dict1dict2,它们包含相同的键,但键的值不同。我想要做的是对每个字典,从最大到最小对值进行排序,然后给每个值一个 1-N 的等级,1 是最大值。从这里,我想获得每个字典中相同键的值的等级差异。例如:

dict1 = a:0.6, b:0.3, c:0.9, d:1.2, e:0.2
dict2 = a:1.4, b:7.7, c:9.0, d:2.5, e:2.0

# sorting by values would look like this:
dict1 = d:1.2, c:0.9, a:0.6, b:0.3, e:0.2
dict2 = c:9.0, b:7.7, d:2.5, e:2.0, a:1.4

#ranking the values would produce this:
dict1 = d:1, c:2, a:3, b:4, e:5
dict2 = c:1, b:2, d:3, e:4, a:5

#computing the difference between ranks would be something like this:
diffs = 
for x in dict1.keys():
    diffs[x] = (dict1[x] - dict2[x])

#diffs would look like this:
diffs[a] = -2
diffs[b] = 2
diffs[c] = 1
diffs[d] = -2
diffs[e] = 1

我知道字典是随机的且不可排序的,但也许有一种方法可以将键和值放入列表中?我面临的主要挑战是获取按值(从大到小)排序的键和值,然后将值更改为其在排序列表中的相应排名。

【问题讨论】:

【参考方案1】:

小字典的简单解决方案是

dict1 = "a":0.6, "b":0.3, "c":0.9, "d":1.2, "e":0.2
dict2 = "a":1.4, "b":7.7, "c":9.0, "d":2.5, "e":2.0
k1 = sorted(dict1, key=dict1.get)
k2 = sorted(dict2, key=dict2.get)
diffs = dict((k, k2.index(k) - k1.index(k)) for k in dict1)

一个更高效、可读性更强的版本,适用于更大的字典:

ranks1 = dict(map(reversed, enumerate(sorted(dict1, key=dict1.get))))
ranks2 = dict(map(reversed, enumerate(sorted(dict2, key=dict2.get))))
diffs = dict((k, ranks2[k] - ranks1[k]) for k in dict1)

【讨论】:

+1。没有多少人以这种方式使用mapreversed。棘手:-) 但我建议使用itertools.imap 来节省一些内存。 同意。通常,出于性能原因,我建议在 map 上使用列表推导或生成器表达式(直到现在才知道 imap),但我认为这是一个更好、更易读的解决方案。荣誉:-) sorted(dict1.items(), key=lambda item: item[1]) 会不会更快,因为这样您就不需要查找字典中的每个值了? @Aleksi:首先,字典查找非常快。我认为sorted(dict1, key=dict1.get) 更快,因为您没有为每个项目调用 Python 函数的开销。当然你的表达式可以写成sorted(dict1.items(), key=operator.itermgetter(1)),去掉lambda函数并使这个参数无效。但其次,您的表达式返回的列表与我的不同。我需要以某种方式摆脱这些价值观。 @Sven:是的,我在想dict((key, rank) for rank, (key, value) in enumerate(sorted(dict1.items(), key=operator.itemgetter(1)))) 中的一些东西,但是如果列表理解比map+reversed 慢,我的观点确实没有实际意义。跨度> 【参考方案2】:

您可能对collections.OrderedDict感兴趣

这是一个示例,我最初的想法是您还在寻找具有按值排序的键的字典,od1od2 是。

d1 = "a":0.6, "b":0.3, "c":0.9, "d":1.2, "e":0.2
d2 = "a":1.4, "b":7.7, "c":9.0, "d":2.5, "e":2.0

od1 = OrderedDict(sorted(d1.items(), key=lambda t: t[1]))
od2 = OrderedDict(sorted(d2.items(), key=lambda t: t[1]))

k1 = od1.keys()
k2 = od2.keys()

diff = dict((k, n - k2.index(k)) for n, k in enumerate(k1))

如果您不需要它们,那么 Sven 解决方案可能会更快。

编辑:说实话没那么快...(sven.py 是他的第二个更高效的版本):

$ cat /tmp/mine.py | time python -m timeit
10000000 loops, best of 3: 0.0842 usec per loop
real    0m 3.69s
user    0m 3.38s
sys 0m 0.03s
$ cat /tmp/sven.py | time python -m timeit
10000000 loops, best of 3: 0.085 usec per loop
real    0m 3.86s
user    0m 3.42s
sys 0m 0.03s

如果有人想发布更大的格式化字典,我也会对其进行测试。

【讨论】:

这是错误的工作工具,提问者并不真正需要有序字典,他只需要一种对值进行排序的方法。 Asker 说:我面临的主要挑战是获取按值排序的键和值OrderedDict 在我看来是正确的工具 我看不出OrderedDict 如何简化生成diffs 字典的任务。你能举一个完整的例子吗? (顺便说一句,不是我的反对票。) 是的,但是看问题。首先你有字典,然后你需要得到值的排名(你不需要有序的字典),然后你想要最终字典中的排名结果。您在任何地方都需要有序字典,它们是适合这项工作的错误工具。例如,看看 Svens 的回答。【参考方案3】:

你用的是什么版本的python?如果是 2.7,请使用 OrderedDict。

根据 Python 2.7 docs:

OrderedDict(sorted(d.items(), key=d.get))

如果您使用的是 Python 2.4-2.6,您仍然可以通过从 pypi here 安装 OrderedDict 来使用它,或者如果您有 setuptools,请运行

easy_install ordereddict

【讨论】:

同意!特别是因为我们的两个答案都是完全有效的解决方案。我也对你的投票表示赞同,以否定做这件事的人的行为。 我没有投反对票,但我认为OrderedDict 在这里没有任何帮助。要实现 OP 想要的,您不需要实际对字典进行排序。而且,你给的key函数是错误的。 哦该死的,你说得对关键功能。我只是直接从文档中复制/粘贴...将编辑。【参考方案4】:

字典不是解决这个问题的正确数据结构。您应该尽快转换为排序列表并仅生成字典作为最终结果。以下示例解决方案尽可能使用迭代器和生成器表达式,以避免在此过程中创建过多(可能很大)的帮助器列表:

def get_ranking(vals):
    '''Return a list of pairs: (key, ranking), sorted by key.'''
    ranking = sorted(((v, k) for k, v in vals.iteritems()), reverse=True)
    return sorted((k, i) for (i, (_v, k)) in enumerate(ranking))

def ranking_diff(rank1, rank2):
    return dict((k, v1 - v2) for (k, v1), (_, v2) in itertools.izip(rank1, rank2))

def get_diffs(dict1, dict2):
    r1 = get_ranking(dict1)
    r2 = get_ranking(dict2)
    return ranking_diff(r1, r2)

print get_diffs(dict1, dict2)
# prints: 'a': -2, 'c': 1, 'b': 2, 'e': 1, 'd': -2

请注意,此解决方案假定两个 dicts 包含完全相同的键。

【讨论】:

以上是关于python字典值排序的主要内容,如果未能解决你的问题,请参考以下文章

python 字典排序

python根据字典的值进行排序:

python练习:字典value值排序,key值排序

python 字典按键值排序

python 字典按键值排序

字典排序