【问题标题】:Python re-order proportion inversely in a dictionaryPython在字典中反向重新排序比例
【发布时间】:2018-03-06 21:22:46
【问题描述】:
A = {0:{'a':1,'b':7, 'weight':0.6}, 
     1:{'a':5,'b':5, 'weight':0.3}, 
     2:{'a':4,'b':6, 'weight':0.1}}

我想根据值b的倒序将inverse_weight分配给每个子字典;

这些b值的顺序

   A[1]['b']  < A[2]['b'] < A[0]['b']
       5      <     6     <    7

他们的体重分别是

      0.6          0.3         0.1    

因此我需要反转它们的权重:

      0.1          0.3         0.6

想要的A应该是这样的

A = {0:{'a':1,'b':7, 'weight':0.6, 'inverse_weight':0.1}, 
     1:{'a':5,'b':5, 'weight':0.3, 'inverse_weight':0.6}, 
     2:{'a':4,'b':6, 'weight':0.1, 'inverse_weight':0.3}}

我不知道如何订购这些b 并反过来申请inverse_weight

【问题讨论】:

  • 你自己尝试过什么吗?
  • 您似乎希望我们为您编写一些代码。虽然许多用户愿意为陷入困境的程序员编写代码,但他们通常只会在发布者已经尝试自己解决问题时提供帮助。展示这种努力的一个好方法是添加Minimal, complete, verifiable example。在发帖前检查您应该完成的intro tour,尤其是How to Ask
  • 这个例子是假的,因为你说A[1]的权重是0.6,但在你的字典里是0.3
  • 一点也不,我正在简化问题并尝试自己做。我尝试使用列表来解决它。但我真的不确定这是正确的方法。
  • 不,我打算分配它,因为我想仅根据 b 的值分配 inverse_weight

标签: python loops dictionary items


【解决方案1】:

您当前列出的愿望权重不正确,因为[1, 2, 0] 的权重应该是[0.3, 0.1, 0.6]。但是,当使用上面列出的正确权重时,您可以使用下面的代码来获得结果:

A = {0:{'a':1,'b':7, 'weight':0.6}, 
 1:{'a':5,'b':5, 'weight':0.3}, 
 2:{'a':4,'b':6, 'weight':0.1}}
new_a = {a:b['weight'] for a, b in A.items()}
inverses = [new_a[c] for _, c in sorted([(A[i]['b'], i) for i in A], key=lambda x:x[0])]
final_inverses = dict(zip([c for _, c in sorted([(A[i]['b'], i) for i in A], key=lambda x:x[0])], inverses[::-1] if not len(inverses)%2 else inverses[len(inverses)//2+1:] +[inverses[len(inverses)//2]] + inverses[:len(inverses)//2]))
final_data = {a:{**b, **{'inverse_weight':final_inverses[a]}} for a, b in A.items()}

输出:

{0: {'weight': 0.6, 'b': 7, 'a': 1, 'inverse_weight': 0.3}, 1: {'weight': 0.3, 'b': 5, 'a': 5, 'inverse_weight': 0.6}, 2: {'weight': 0.1, 'b': 6, 'a': 4, 'inverse_weight': 0.1}}

【讨论】:

    【解决方案2】:

    方法

    • 创建对列表(A[id]['b'], id)
    • 对此列表进行排序
    • 以相反的顺序添加倒置的权重

    代码

    lpairs = [(A[id]['b'], id) for id in A]
    lpairs.sort()
    for i in range(len(lpairs)):
        A[lpairs[i][1]]["inverted_weight"] = A[lpairs[len(lpairs)-1-i][1]]["weight"]
    

    示例:

    对于数据:

    A = {0:{'a':1,'b':7, 'weight':0.6}, 
         1:{'a':5,'b':5, 'weight':0.3}, 
         2:{'a':4,'b':6, 'weight':0.1}}
    

    这给出了:

    {0: {'a': 1, 'weight': 0.6, 'b': 7, 'inverted_weight': 0.3},
     1: {'a': 5, 'weight': 0.3, 'b': 5, 'inverted_weight': 0.6},
     2: {'a': 4, 'weight': 0.1, 'b': 6, 'inverted_weight': 0.1}}
    

    注意:

    您在问题中给出的示例不正确,因为您说 A[1] 的权重是 0.6 但它是 0.3。

    【讨论】:

    • 不知道列表可以根据第一个元组元素排序,谢谢!
    • 列表按第一个排序,如果相等则按第二个排序,以此类推
    • @LouisSugy 您可以同时创建和排序lpairslpairs = sorted((A[id]['b'], id) for id in A),您也可以稍微缩短权重调用:A[lpairs[~i][1]]["weight"]bpaste.net/show/fd30a285fc59
    • 我相信这样更易读,而且还不会太长。我不会在我自己的代码中写A[lpairs[len(lpairs)-1-i][1]]["weight"],但 OP 似乎是一个初学者(问题相当基本)。
    【解决方案3】:

    似乎是在一种方法中使用zipsortedreversed 的好借口。

    A = {0: {'a': 1, 'b': 7, 'weight': 0.6},
         1: {'a': 5, 'b': 5, 'weight': 0.3},
         2: {'a': 4, 'b': 6, 'weight': 0.1}}
    
    # Make sorted list from A.items(), sorted by weight:
    a_list = sorted(list(A.items()), key=lambda item: item[1]['weight'])
    
    # Make a reversed copy of that list:
    b_list = reversed(A_list)
    
    A = {}
    for a_item, b_item in zip(a_list, b_list):
        a_item[1]['inverse_weight'] = b_item[1]['weight']
        A[a_item[0]] = a_item[1]
    

    【讨论】:

    • 不,我打算将0.1分配给2,因为我想仅根据b的值分配inverse_weight。
    • 加勒特是对的:示例不正确,参见我对问题的评论
    • 你的意思是想让kth 最大b 的元素的权重为kth 最小b 的元素的权重?如果是这样,请将 lambda 更改为 lambda item: item[1]['b']。我不确定你在问什么。
    猜你喜欢
    • 2011-02-16
    • 2017-09-12
    • 1970-01-01
    • 1970-01-01
    • 2019-05-14
    • 2023-02-07
    • 2019-09-18
    • 2017-12-17
    • 2021-12-30
    相关资源
    最近更新 更多