【问题标题】:How to order a dictionary of dictionaries based on inner dictionary's value如何根据内部字典的值对字典进行排序
【发布时间】:2014-10-30 22:44:58
【问题描述】:

我在 Python 中有一个字典,它的字典值如下:

{'q1': {'d1': 1.2 , 'd5': 5.2}, 
 'q2': {'d4': 3.23, 'd7': 3.9 , 'd8': 4.1},
 'q3': {'d3': 0.5}}

我想对这本字典进行排名,并根据浮点数的递减值显示 d 变量 与它们关联的值。

结果应该是这样的:

['d5', 'd8', 'd7', 'd4', 'd1', 'd3']

这是我为填写字典而编写的部分代码:

if q not in result.keys():
    result[q] = {id:rsv[id]}
elif id not in result[q]:
    result[q][id]=rsv[id]

我想显示按 rsv 值排序的 id 。 有没有办法做到这一点?或者是否有任何替代解决方案可以根据一系列值对字典进行排名?

【问题讨论】:

  • 现在嵌套字典中有多个键。 应该按什么键对这些字典进行排序?要返回什么密钥?
  • 您是否试图将所有嵌套字典视为一个?
  • 我已根据您的 cmets 对其中一个答案更新了您的帖子(已删除)。这种信息需要成为您问题的一部分,而不是隐藏在 cmets 中。
  • 我想根据第二个字典的值对第一个字典的键进行排序和显示!也许这种方法是错误的。整个想法是根据一些值对字典进行排序。我也愿意接受除 dict of dicts 以外的任何解决方案。
  • 我是否理解正确,您想根据内部字典的值按顺序显示外部字典键 q1、q2 和 q3?应该如何评估具有多个键值对的内部 dict 以进行排序?

标签: python sorting python-3.x dictionary


【解决方案1】:

由于 op 将规范更改为在内部 dicts 中有多个键值对,我想我会展示一个借鉴 @jarno-lamberg 的一些想法的解决方案。这里的关键是,因为看起来外部映射无关紧要,所以我首先抓取所有的 dicts 并将它们展平成一个元组列表。

d =  {'q1': {'d1': 1.2 , 'd5': 5.2}, 
      'q2': {'d4': 3.23, 'd7': 3.9 , 'd8': 4.1},
      'q3': {'d3': 0.5}}
d_flattened = [(k,v) for temp_d in d.values() for k,v in temp_d.items()]
d_sorted = sorted(d_flattened, key=lambda i: i[1], reverse=True)
print(', '.join(k for k,v in d_sorted))

【讨论】:

  • @Papar:请注意,这正是我的解决方案完成的。
【解决方案2】:

我的目标是代码清晰,并认为在这种情况下,最好多写几行代码。请注意,使用缩进是为了更好地显示结构。

根据我的经验,此答案包含经常需要的中间结果。它将它们保存为字典,直到最后只需要键。

首先,Python 2.x 版本只是因为:

d = {'q1': {'d1': 1.2 , 'd5': 5.2},
     'q2': {'d4': 3.23, 'd7': 3.9 , 'd8': 4.1},
     'q3': {'d3': 0.5}}

# First, flatten to a list of one key-value pair dictionaries
inner_dicts = [
    dict([(k,v)]) 
    for inner_d in d.values() 
        for (k, v) in inner_d.items()]

# Second, sort that list based on the value in each dict
dictlist_sorted = sorted(
    inner_dicts, 
    key=lambda temp_d: temp_d.values()[0], 
    reverse=True)

# Third, extract the key of each dict
keys_sorted = [temp_d.keys()[0] for temp_d in dictlist_sorted]

print keys_sorted

二、Python 3版本:

d = {'q1': {'d1': 1.2 , 'd5': 5.2},
     'q2': {'d4': 3.23, 'd7': 3.9 , 'd8': 4.1},
     'q3': {'d3': 0.5}}

# First, flatten to a list of one key-value pair dictionaries
inner_dicts = [
    dict([(k,v)]) 
    for inner_d in d.values() 
        for (k, v) in inner_d.items()]

# Second, sort that list based on the value in each dict
dictlist_sorted = sorted(
    inner_dicts, 
    key=lambda temp_d: list(temp_d.values())[0], 
    reverse=True)

# Third, extract the key of each dict
keys_sorted = [list(temp_d.keys())[0] for temp_d in dictlist_sorted]

print(keys_sorted)

【讨论】:

  • 每个内部字典将有多个键值对。是否可以对这种字典进行排序?
  • @Papar,我更新了我的答案(即使你已经接受了另一个答案)。
【解决方案3】:

对值进行排序,提取为值和键的元组(按此顺序),然​​后提取键:

[key for value, key in sorted(
    (item[::-1] for d in outer.values() for item in d.items()), 
    reverse=True)]

(item[::-1] for d in outer.values() for item in d.items()) 表达式从每个嵌套字典值中提取 (key, value) 对,颠倒键和值以便于排序。

然后排序取第一个值,颠倒过来,之后外部列表推导再次仅提取键。

演示:

>>> d = {'q1': {'d1': 1.2 , 'd5':5.2}, 'q2': {'d4': 3.23, 'd7':3.9 , 'd8':4.1}, 'q3': {'d3': 0.5}}
>>> outer = {'q1': {'d1': 1.2 , 'd5':5.2}, 'q2': {'d4': 3.23, 'd7':3.9 , 'd8':4.1}, 'q3': {'d3': 0.5}}
>>> sorted((item[::-1] for d in outer.values() for item in d.items()), reverse=True)
[(5.2, 'd5'), (4.1, 'd8'), (3.9, 'd7'), (3.23, 'd4'), (1.2, 'd1'), (0.5, 'd3')]
>>> [key for value, key in sorted(
...     (item[::-1] for d in outer.values() for item in d.items()), 
...     reverse=True)]
['d5', 'd8', 'd7', 'd4', 'd1', 'd3']

【讨论】:

  • 谢谢,但我收到此错误:'dict_items' 对象不支持索引
  • 是的,顺便说一句,我的字典的名称是结果,这是我尝试过的代码:[key for value,key in sorted((result[q].items()[0][: :-1] for result[q] in result.values()))]
  • @Papar:将我的代码中的outer 替换为result。仅此而已,或者先做outer = result
  • 它只返回一个值,而且这个值也不应该是列表中的第一个。我应该提一下,内部字典不像元组,可以有多个这样的键: {'q1': {'d1': 1.2 , 'd5':5.2}, 'q2': {'d4': 3.23, 'd7':3.9 , 'd8':4.1}, 'q3': {'d3': 0.5}}
  • @Papar:然后用该信息更新您的问题。在这种情况下会选择什么键?如果没有准确的问题描述,我无法回答。
【解决方案4】:

我会分两步处理这个问题:排序,然后显示。对于排序,使用一个键函数:

d_sorted = sorted(d.items(), reverse=True, key=lambda x: list(x[1].values())[0])

然后,显示数据:

print(', '.join(list(x[1].keys())[0] for x in d_sorted))

一般来说这是一个好主意,因为您可能希望完全重用已排序的数据。

【讨论】:

  • OP 使用的是 Python 3,所以 .keys()[0] 在这里会失败。
  • @martijn-pieters 是的。固定。
  • 除了打印调用缺少括号。
猜你喜欢
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
  • 2021-05-27
  • 1970-01-01
  • 1970-01-01
  • 2019-01-25
相关资源
最近更新 更多