2016-02-25 209 views
1

我正在編寫一個程序,需要使用此函數向xml文件添加依賴項。這段代碼很有用,但我想問一下是否有更多pythonic的方式來這樣做。在Python中迭代字典列表時迭代字典

我相信我以非pythonic的方式做的部分是嵌套for循環。是否有更好的方法來迭代字典和每個值的列表?

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關於嵌套for循環。如果需要,可以將代碼重構爲使用comprehensions,但由於最內層的語句是副作用的,並且不打算返回值,因此它不是明智的選擇。把它包裝在lambda或其他東西中,這樣它就可以在理解中出現。我相信你的循環方法是乾淨的,好的,易於閱讀的代碼,它可能不是一個很好的時間來使它成爲所謂的「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 shell說,字典最多隻有1個參數。 –

0

您可以使用collections.ChainMap將您的三個字典合併爲一個類似字典的映射。或者,由於您不關心這些值,因此您可以將它們的密鑰合併爲一個set

使用它來避免嵌套循環並不重要。嵌套循環可以是完美的Pythonic,儘管如果嵌套變得太深,您可能想要將一些內部比特分解爲函數。

您可能想在這裏使用ChainMapset的真正原因是爲了避免搜索您的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

謝謝,這是非常豐富的。 –