【问题标题】:Counting distinct dictionary values计算不同的字典值
【发布时间】:2018-09-23 19:30:28
【问题描述】:

我有这个dictionary (key,list)

index={'chair':['one','two','two','two'],'table':['two','three','three']}

我想要这个

#1. number of times each value occurs in each key. ordered descending
indexCalc={'chair':{'two':3,'one':1}, 'table':{'three':2,'two':1}}
#2. value for maximum amount for each key
indexMax={'chair':3,'table':2}
#3. we divide each value in #1 by value in #2 
indexCalcMax={'chair':{'two':3/3,'one':1/3}, 'table':{'three':2/2,'two':1/2}}

我认为我应该使用 lambda 表达式,但不知道如何做到这一点。有什么帮助吗?

【问题讨论】:

  • 您想要全部 3 个还是只想要最终输出?
  • @vash_the_stampede,我想要所有 3 个字典,indexCalc、indexMax、indexCalcMax。
  • 您的原始索引不能包含该数据,因为值是集合并且集合必须是唯一的。你的意思是用列表代替吗?
  • @DanielRoseman,我知道如果你这样说,那将把它转移到集合中,但为了表示的目的,我这样说。其实就是List

标签: python python-3.x list dictionary


【解决方案1】:

首先,将您的值正确定义为列表:

index = {'chair': ['one','two','two','two'], 'table': ['two','three','three']}

然后将collections.Counter 与字典推导一起使用:

from collections import Counter
  1. 每个值在每个键中出现的次数。
res1 = {k: Counter(v) for k, v in index.items()}
  1. 每个键的最大数量值
res2 = {k: v.most_common()[0][1] for k, v in res1.items()}
  1. 我们将#1 中的每个值除以#2 中的值
res3 = {k: {m: n / res2[k] for m, n in v.items()} for k, v in res1.items()}

【讨论】:

  • 整洁。谢谢。将尝试了解上述代码的工作原理,这将有很大帮助
【解决方案2】:
index={'chair':{'one','two','two','two'},'table':{'two','three','three'}}

问题:{} 正在创建一个集合。所以你应该考虑将它转换成列表。

现在找到您的解决方案:

from collections  import Counter


index={'chair': ['one','two','two','two'],'table':['two','three','three']}
updated_index = {'chair': dict(Counter(index['chair'])), 'table': dict(Counter(index['table']))}
updated_index_2 = {'chair': Counter(index['chair']).most_common()[0][1], 'table': Counter(index['table']).most_common()[0][1]}
print(updated_index)
print(updated_index_2)

您可以使用 python 集合库 Counter 来查找计数,而无需编写任何 lambda 函数。

{'chair': {'one': 1, 'two': 3}, 'table': {'two': 1, 'three': 2}}

{'椅子': 3, '桌子': 2}

【讨论】:

  • 感谢您的评论,已将其更新为列表。有没有通用的方案来解决我的问题?
【解决方案3】:

首先,您在创建 index 字典的方式上存在错误。您应该将列表作为每个字典的元素,您当前有集合。集合会自动进行重复数据删除,因此您将无法从那里获得正确的计数。

您应该将索引更正为:

index={'chair':['one','two','two','two'],'table':['two','three','three']}

您可以使用 Python 3 中的 Counter moduledict 模块的子类)为 indexCalc 中的每个条目生成您想要的内容。计数器将创建一个带有键的字典,以及该键在集合中存在的次数。

indexCalc = {k, Counter(v) for k, v in index}

indexCalc 看起来像这样:

{'chair': Counter({'two': 3, 'one': 1}), 'table': Counter({'three': 2, 'two': 1})}

我们可以很容易地找到每个子字典中最大值对应的索引:

indexMax = {k: max(indexCalc[k].values()) for k in indexCalc}

indexMax 看起来像这样:

{'chair': 3, 'table': 2}

您可以使用以下推导式创建indexCalcMax,这有点难看:

indexCalcMax = {k: {val: indexCalc[k][val] / indexMax[k] for val in indexCalc[k]} for k in indexCalc}

这是这个循环的字典理解翻译:

for k in indexCalc:
  tmp = {}
  for val in indexCalc[k]:
    tmp[val] = indexCalc[k][val] / float(indexMax[k])
  indexCalcMax[k] = tmp

【讨论】:

    【解决方案4】:

    我知道这是次优的,但我不得不将其作为一个思考练习:

    indexCalc = {
        k: {key: len([el for el in index[k] if el == key]) for key in set(index[k])} 
        for k in index
    }
    

    正如建议的那样,不完全是 lambda,而是理解...不要在生产中使用此代码 :) 这个答案只是部分的,您可以使用类比并提出您需要的其他两个结构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-01
      • 2018-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-30
      • 1970-01-01
      相关资源
      最近更新 更多