2016-02-25 2 views
1

Я пишу программу и должен использовать эту функцию для добавления зависимостей в xml-файл. Этот код работает, но я хотел бы спросить, есть ли более питонический способ сделать это.Итерация по словарю при повторении словарного списка в Python

Часть, которую, я считаю, я делаю непитоновым способом, представляет собой вложенный цикл. Есть ли лучший способ перебора списка словарей и каждого значения?

def add_Dependencies(self): 
     """ Adds the dependencies in a feature using dictionaries. When 
      a feature is loaded, its dependencies are added to 
      dictionaries. Three for each type of software that the 
      dependencies are categorized as.""" 

     dependency_dict_list = [ 
      self.os_dict, self.visual_dict, self.audio_dict 
      ] 

     dependencies = self.dependencies 
     for dictionary in dependency_dict_list:             
      for feature, software in dictionary.items():            
       if all(dependency.text != feature for dependency in dependencies): 
        etree.SubElement(dependencies,"Dependency", Software = software).text = feature 
+8

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

+0

Является ли 'self.dependencies' пустым до вызова этой функции? Похоже, что у вас будет гораздо более быстрый код, если вы сначала объедините несколько словарей (используя структуру данных с поиском ключевых слов O (1)) и только потом создайте XML-элементы. – Blckknght

+0

@Blckknght self.dependencies будет объектом lxml (должен был указать, что.) Зависимость в зависимостях - это дети. Я посмотрю на это. –

ответ

0

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

all_dependencies = dict(self.os_dist, **self.visual_dict) 
all_dependencies.update(self.audio_dict) 

for feature, software in dictionary.items(): 
    if not any(dependency.text == feature for dependency in dependencies): 
     etree.SubElement(dependencies,"Dependency", Software = software).text = feature 
+0

Не могли бы вы объяснить, как работает первая линия? Если это не будет большой проблемой. При попытке сделать что-то подобное в IDLE, чтобы увидеть, как это работает, появляется сообщение об ошибке. –

+0

'dict.update()' возвращает 'None', поэтому ваши' all_dependencies' будут 'None'. – gil

+0

Я вижу, что вы изменили код, но оболочка python говорит, что dict ожидает не более 1 аргумента. –

0

Вы можете использовать collections.ChainMap, чтобы объединить свои три словарей в одном словаре, как отображение. Или, поскольку вы не заботитесь о значениях, вы можете объединить их ключи в set

Это не очень важно использовать это, чтобы избежать вложенных циклов. Вложенные петли могут быть совершенно Pythonic, хотя вы можете захотеть включить некоторые внутренние биты в функции, если вложенность становится слишком глубокой.

Реальная причина, вы можете захотеть использовать ChainMap или set здесь, чтобы избежать O(N**2) выполнения сложности поиска вашего XML-дерева, чтобы избежать дублирования зависимостей. То, что они также устраняют уровень гнездования, является незначительным побочным эффектом.

попробовать что-то вроде этого:

new_dependencies = (set(self.os_dict).union(self.visual_dict, self.audio_dict) - 
        set(dependency.text for dependency in self.dependencies)) 

for feature in new_dependencies: 
    etree.SubElement(self.dependencies,"Dependency", Software = software).text = feature 
+0

Спасибо, это было очень информативно. –

Смежные вопросы