Python 通过某些父标签跟踪某些属性计数组

Python keep track of certain attribute counts group by some parent tags

我需要跟踪按父标签属性分组的子标签中某些属性的计数 在下面的例子中

  <Unit ...>
    <Unit type="1">
      <Result code1="1" code2="1" />
    <Unit type="2">
      <Result code1="1" code2="1" />
    <Unit type="1">
      <Result code1="444" code2="1" />
    <Unit type="1">
      <Result code1="444" code2="1" />
    <Unit type="2">
      <Result code1="1025" code2="1" />
      .
      .
      .
      .

我需要跟踪按 code1 和 code2 的值分组的所有结果标签的总和:最终结果类似于

单位类型 1 的代码 1 计数:{'1': 1, '444':2} code1 计数单位类型 2:{'1':1 , '1025':1}

code2 属性相同

单元类型 1 的代码 2 计数:{'1': 3} 代码 1 计数单位类型 2:{'1':2}

其他属性代码2相同

我用了类似

的东西
for unit in root.iter('Unit'):
    #print(dut.attrib)
    unit_type = int(unit.get('type'))

    code1_map = {}

    
    code1_type_map[siteNumber] = {}

   for result in root.iter('Result'):
        code1 = int(result.get('code1'))
        code2 = int(result.get('code2'))

        if code1 in code1_map:
            code1_map[code1] +=1
        else:
            code1_map[code1] = 1

        code1_type_map[unit_type]= code1_map


#print results:
for key, value in code1_type_map.items():
    print("==>site : value " , key , ' , ' , value)
    for code1, cnt in value.items():
        print(" code1 , count " , code1 , ' , ' , cnt )

似乎总是给出总计数,没有通过属性 code1 和 code2 的值分隔

感谢任何帮助。

您的代码有一些问题,所以这里有一些细分:

问题 1: 此代码为每个 Unit 标记重新初始化 code1_map,这意味着您看到的结果可能不是总数,而是 列表中的最后一个条目

for unit in root.iter('Unit'):
    #print(dut.attrib)
    unit_type = int(unit.get('type'))

    code1_map = {}

    code1_type_map[siteNumber] = {}

问题 2: 这段代码 运行 每次 运行 都会有一张新地图,再次参考我上面的评论 - 这只会得到最后的结果,而不是所有结果的总和。

此外,您在这里创建了一个 code2 变量,但从未使用过它。我相信您最初的问题是您想要两个总和,而不仅仅是 code1 结果的总和。

    for result in root.iter('Result'):
        code1 = int(result.get('code1'))
        code2 = int(result.get('code2'))

        if code1 in code1_map:
            code1_map[code1] +=1
        else:
            code1_map[code1] = 1

        code1_type_map[unit_type]= code1_map

现在让我们开始解决问题;

import json

# -- first, we create the variable that will hold our results
code1_results = dict()
code2_results = dict()

# -- second, we start iterating, assuming you're working with 
# -- xml.elementTree.Element here.
for unit_tag in root.iter('Unit'):
    # -- store the unit type in an easily accessible variable
    unit_type = unit_tag.get('type')

    # -- we will keep results per unit type, per code type.
    if unit_type not in results:

        # -- we pre-initialize the dictionary so it's easier to work with
        code1_results[unit_type] = dict()
        code2_results[unit_type] = dict()
    
    # -- iterate here as well in case there are multiple results
    for result_tag in unit_tag.iter('Result'):
        code1 = result_tag.get('code1') or '0'
        code2 = result_tag.get('code2') or '0'

        # -- if this is a new number, make a new counter
        if not code1_results[unit_type].get(code1):
            code1_results[unit_type][code1] = 0

        # -- if this is a new number, make a new counter
        if not code2_results[unit_type].get(code2):
            code2_results[unit_type][code2] = 0

        code1_results[unit_type][code1] += 1
        code2_results[unit_type][code2] += 1

# -- print the results as JSON or however you like
print(json.dumps(code1_results, indent=4, sort_keys=True))
print(json.dumps(code2_results, indent=4, sort_keys=True))

类似下面的内容

from collections import defaultdict
import xml.etree.ElementTree as ET

xml = ''' <Unit>
    <Unit type="1">
      <Result code1="1" code2="1" />
      </Unit> 
    <Unit type="2">
      <Result code1="1" code2="1" />
      </Unit> 
    <Unit type="1">
      <Result code1="444" code2="1" />
     </Unit>  
    <Unit type="1">
      <Result code1="444" code2="1" />
      </Unit> 
    <Unit type="2">
      <Result code1="1025" code2="1" />
     </Unit>
    </Unit>
    '''
data = defaultdict(dict)
root = ET.fromstring(xml)
for u in root.findall('.//Unit'):
    r = u.find('Result')
    data[u.attrib['type']][r.attrib['code1']] = r.attrib['code2']
print(data)

输出

defaultdict(<class 'dict'>, {'1': {'1': '1', '444': '1'}, '2': {'1': '1', '1025': '1'}})