Более питоновский способ выбора нескольких типов элементов из помеченных данных

У меня есть некоторые помеченные данные, которые я обрабатываю с помощью lxml. Когда я открываю файл, я не знаю, прежде чем файл будет открыт, если у меня есть один или несколько из трех типов элементов (у меня может быть один, два или три разных элемента и несколько экземпляров любого типа, который у меня есть)

Мне нужна информация об этих элементах, которая содержится в дочерних тегах элемента

<element_type_1> <name>joe smith</name> </element_type_1> <element_type_2> <name>mary smith</name> </element_type_2> <element_type_3> <name>patrick smith</name> </element_type_3> 

Таким образом, в этом случае у меня есть все три типа, но только один из каждого типа, но может быть до какого-либо произвольного большого числа любого типа.

Я получаю элементы, используя cssselect 3 раза в своей функции

 def get_types(myTree): type_dict=defaultdict(list) type_dict['type_1']=myTree.cssselect('element_type_1') type_dict['type_2']=myTree.cssselect('element_type_2') type_dict['type_3']=myTree.cssselect('element_type_3') ret type_dict 

Это кажется излишне избыточным

Я что-то упустил, чтобы немного почистить?

FYI Я делаю это, потому что для каждого типа я должен сопоставлять некоторые другие данные из соответствующего документа

Ранние ответы подсказывают, что мне нужно немного уточнить – я хочу, чтобы три раза не проедал дерево

Вы можете сделать это:

 for i in range(1, 4): type_dict['type_%d' % i] = myTree.cssselect('element_type_%d' % i) 

Зависит, знаете ли вы, как это выглядит. Использование переменной в качестве ключа может быть простой вещью, которая поможет вам немного улучшить ее.

 def get_types(myTree): type_dict=defaultdict(list) for i in range(1,4): x = 'type_%d' % i y = 'element_type_%d' % i type_dict[x] = myTree.csselect(y) return type_dict 

Я не знаю точно, как вы идентифицируете эти «типы», если вы не знаете их имена заранее. Выполняют ли они какой-то фиксированный шаблон, который вы можете искать?

Например, вы можете сделать что-то вроде этого:

 d = {} typeelements = "*[starts-with(local-name(), 'element_type_')]" for e in myTree.xpath(typeelements) typename = e.tag.split('_',1)[1] d[typename] = e 

Или более лаконично:

 d = {e.tag.split('_',1)[1]:e for e in myTree.xpath(typeelements)} 

Кроме того, вы можете выбрать элемент на основе некоторых критериев в самом элементе. В вашем примере все name имеют name , поэтому вы можете использовать такой путь:

 typeelements = '*[name]' 

Или вы можете комбинировать оба требования:

 typeelements = "*[starts-with(name(), 'element_type_')][name]" 

Или вы можете перебирать множество известных тегов, которые ищут соответствующие элементы. Когда вы найдете элемент, добавьте (tag, value) в dict. Должен работать нормально.