Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python字典值排序_Python_Sorting_Dictionary - Fatal编程技术网

python字典值排序

python字典值排序,python,sorting,dictionary,Python,Sorting,Dictionary,我有两个字典,dict1和dict2,它们包含相同的键,但键的值不同。我要做的是对每个字典,从最大值到最小值排序,然后给每个值一个秩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,

我有两个字典,
dict1
dict2
,它们包含相同的键,但键的值不同。我要做的是对每个字典,从最大值到最小值排序,然后给每个值一个秩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
我知道字典应该是随机的,不可排序的,但也许有一种方法可以将键和值放入列表中?我面临的主要挑战是获取按值(从大到小)排序的键和值,然后将值更改为排序列表中的相应等级

您可能对

这是一个示例,我最初的想法是,您也在寻找键按值排序的字典,
od1
od2

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是他的第二个更高效的版本):


如果有人想发布格式化的更大的dicts,我也会测试它们。

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

根据Python 2.7:

如果您使用的是Python2.4-2.6,您仍然可以通过从pypi安装OrderedDict来使用它,或者如果您已经安装了OrderedDict,请运行


对于小型dict,一个简单的解决方案是

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)
更高效、可读性更低的版本,适用于更大的DICT:

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)

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

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}

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

同意!特别是因为我们的两个答案都是完全有效的解决方案。我也投了你的一票,以否定做这件事的人的行为。我没有投反对票,但我认为,
OrderedDict
在这里没有任何帮助。要实现OP想要的功能,实际上不需要对字典进行排序。此外,你给出的关键功能是错误的。哦,该死,你对关键功能的看法是正确的。我只是直接从文档中复制/粘贴。。。将编辑。+1。没有多少人用这种方式使用
map
reversed
。棘手:-)但我建议使用
itertools.imap
来节省一些内存。同意。通常,出于性能原因,我建议使用列表理解或生成器表达式而不是map(直到现在才知道imap),但我认为这是一个更好、更可读的解决方案。Kudos:-)不会更快排序(dict1.items(),key=lambda item:item[1])因为这样你就不需要在字典中查找每一个值了?@Aleksi:首先,字典查找相当快。我认为
sorted(dict1,key=dict1.get)
更快,因为您没有为每个项目调用Python函数的开销。当然,表达式可以写成排序的(dict1.items(),key=operator.itermgetter(1)),从而消除lambda函数并使此参数无效。但是第二,您的表达式返回的列表与我的不同。我需要以某种方式去除这些值。@Sven:是的,我想在enumerate(排序的(dict1.items(),key=operator.itemgetter(1))中的
dict((key,rank)for rank,(key,value))行中做一些事情,但是如果列表理解比
map
+
倒转的
,我的观点确实没有意义。这是一个错误的工作工具,询问者并不需要一个有序的字典,Asker说:我面临的主要挑战是获得按值排序的键和值,在我看来,
orderedict
似乎是正确的工具。我看不出
orderedict
如何简化生成
diff
字典的任务。你能举个完整的例子吗?(顺便说一句,不是我的反对票。)是的,但看看问题。首先您有字典,然后您需要获得值的排序(对于这些值,您不需要有序字典),然后您需要在最终的字典中获得排序结果。你在任何地方都不需要有序的词典,它们是完成这项工作的错误工具。例如,看看斯文斯的答案。
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)
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}