英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论