使用Python生成XML中usage类别唯一组合并统计物品数量
解决Python读取XML统计usage组合物品数量的问题
核心思路
要搞定这个问题,关键是把每个物品的usage组合转换成无序且可哈希的类型(比如frozenset),这样就能作为字典的键来统计对应物品的数量,同时天然避免重复统计顺序不同的同一组合(比如{Town, Office}和{Office, Town}会被识别为同一个组合)。
完整实现代码
import xml.etree.ElementTree as ET # 解析XML文件 tree = ET.parse('types.xml') root = tree.getroot() # 用于统计每个usage组合对应的物品数量 usage_count = {} # 遍历每个物品类型节点 for item_type in root.findall('./type'): # 收集当前物品的所有usage名称,用set保证无序和去重 usages = set() for usage_elem in item_type.findall('usage'): usage_name = usage_elem.get('name') usages.add(usage_name) # 转成frozenset(不可变集合),才能作为字典的键 usage_key = frozenset(usages) # 更新统计计数 if usage_key in usage_count: usage_count[usage_key] += 1 else: usage_count[usage_key] = 1 # 格式化输出结果 print("不同usage组合的物品数量统计:") for combo, count in usage_count.items(): # 把无序集合转成有序列表,提升可读性 sorted_combo = sorted(combo) print(f"组合 {sorted_combo}:{count} 个物品")
代码说明
- XML解析与遍历:通过
ElementTree加载文件,逐个处理每个<type>节点(每个节点对应一个物品)。 - 单个物品的usage收集:用
set存储单个物品的所有usage,自动处理无序性,同时避免同一物品内重复的usage(即使XML里没重复,用set更稳妥)。 - 可哈希键转换:普通
set是可变类型,不能作为字典的键,转成frozenset(不可变集合)后就能正常用作统计字典的键。 - 统计逻辑:遍历过程中更新每个组合的物品计数,存在则加1,不存在则初始化为1。
- 友好输出:把无序的
frozenset转成排序后的列表,让输出结果更易读。
扩展:统计所有usage子组合
如果需要统计所有可能的usage子组合(比如某个物品有Town, Office, School,要单独统计{Town}、{Town, Office}等所有非空子组合的物品数量),可以用itertools生成所有子集:
import itertools # 在获取当前物品的usages集合后,替换原统计逻辑为以下代码 for i in range(1, len(usages)+1): # 生成所有长度为i的子组合 for subset in itertools.combinations(sorted(usages), i): subset_key = frozenset(subset) if subset_key in usage_count: usage_count[subset_key] += 1 else: usage_count[subset_key] = 1
这段代码会把每个物品的所有非空usage子组合都纳入统计,比如含3个usage的物品会生成7个不同的子组合。
内容的提问来源于stack exchange,提问作者talkinggoat
相关产品推荐
相关产品推荐

