在Python中选择字典中的一个子键。

huangapple go评论61阅读模式
英文:

select a subkey in a dictionary in Python

问题

我正在使用一个具有多个键的字典,就像下面的示例:

import pandas as pd

dict = {'Mouses': {'White': {'Small': 1, 'Big': 2}, 'Black': {'Small': 3, 'Big': 4}},
        'Cats':   {'White': {'Small': 5, 'Big': 6}, 'Black': {'Small': 7, 'Big': 8}},
        'Dogs':   {'White': {'Small': 9, 'Big': 1}, 'Black': {'Small': 2, 'Big': 3}}}

如果我想要获取 ‘Big’-‘White’-‘Cats’ 的数量,这很简单。但如果我想要所有 ‘White’-‘Cats’ 呢?或者所有的 ‘Dogs’?是否有一种简单的方法来访问给定子键中的所有值?一种对所有值进行求和的子键查询方式。先谢谢。

英文:

I'm working with a dictionary with multiple keys, like the following:

import pandas as pd

dict = {'Mouses': {'White': {'Small': 1, 'Big': 2}, 'Black': {'Small': 3, 'Big': 4} },
        'Cats':   {'White': {'Small': 5, 'Big': 6}, 'Black': {'Small': 7, 'Big': 8} }, 
        'Dogs':   {'White': {'Small': 9, 'Big': 1}, 'Black': {'Small': 2, 'Big': 3} } }

If I want to get the number of 'Big'-'White'-'Cats', it's simple. But what if I want all the 'White'-'Cats'? Or All the 'Dogs'? Is there a way to easily access all values within a given subkey? A sort of query of subkeys with a sum over all values. Thanks in advance.

答案1

得分: 3

你可以编写一个递归函数,它会根据层次结构深入字典并使用或聚合结果(all用作通配符表示聚合):

def zooCount(z, key=all, *subKeys):
    if not isinstance(z, dict): return z
    if key is all:
        return sum(zooCount(v, *subKeys) for v in z.values())
    return zooCount(z.get(key, 0), *subKeys)

zoo = {'Mice': {'White': {'Small': 1, 'Big': 2},
                'Black': {'Small': 3, 'Big': 4}},
       'Cats': {'White': {'Small': 5, 'Big': 6},
                'Black': {'Small': 7, 'Big': 8}},
       'Dogs': {'White': {'Small': 9, 'Big': 1},
                'Black': {'Small': 2, 'Big': 3}}}

print(zooCount(zoo, "Cats", "White", "Small")) # 5
print(zooCount(zoo, all, "White", "Small")) # 15
print(zooCount(zoo, all, "Black", all)) # 27
print(zooCount(zoo, "Dogs", "Blue", all)) # 0

# 你可以省略尾部的通配符:

print(zooCount(zoo, "Cats", "White")) # 11
print(zooCount(zoo, "Dogs")) # 15
print(zooCount(zoo)) # 51

如果你不熟悉递归,也可以使用迭代方法,逐渐深入层次结构的级别,构建一个包含匹配键的字典列表,直到列表达到最深的级别并包含要添加的过滤数字:

def zooCount(z, species=all, color=all, size=all):
    result = [z]                      # 字典列表
    for key in (species, color, size):  # 过滤下一级
        result = [v for d in result for k, v in d.items() if key in (k, all)]
    return sum(result) # 最终列表是要相加的数字
英文:

You could write a recursive function that drills down the dictionary using or aggregating results as it goes down the hierarchy (all is used as wildcard to indicate aggregation):

def zooCount(z,key=all,*subKeys):
    if not isinstance(z,dict): return z
    if key is all:
       return sum( zooCount(v,*subKeys) for v in z.values()) 
    return zooCount(z.get(key,0),*subKeys)

zoo = {'Mice':   {'White': {'Small': 1, 'Big': 2}, 
                  'Black': {'Small': 3, 'Big': 4} },
       'Cats':   {'White': {'Small': 5, 'Big': 6}, 
                  'Black': {'Small': 7, 'Big': 8} }, 
       'Dogs':   {'White': {'Small': 9, 'Big': 1}, 
                  'Black': {'Small': 2, 'Big': 3} } }

print(zooCount(zoo, "Cats","White", "Small")) # 5
print(zooCount(zoo, all,   "White", "Small")) # 15 
print(zooCount(zoo, all,   "Black", all))     # 27
print(zooCount(zoo, "Dogs","Blue",  all))     # 0

# you can omit trailing wildcards:

print(zooCount(zoo, "Cats", "White"))    # 11
print(zooCount(zoo, "Dogs"))             # 15        
print(zooCount(zoo))                     # 51 

If you're not comfortable with recursion, an iterative approach can be used, by progressively going down the hierarchical levels building a list of dictionary with matching keys until the list reaches the deepest level and contains the filtered numbers to add up:

def zooCount(z,species=all,color=all,size=all):
    result = [z]                      # list of dictionaries
    for key in (species,color,size):  # filter next level
        result = [v for d in result for k,v in d.items() if key in (k,all)]
    return sum(result) # final list is numbers to add up

huangapple
  • 本文由 发表于 2023年6月26日 23:09:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76557975.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定