2016-11-16 39 views
0

我期待最大限度地優化運行此塊的代碼:什麼是在Python字典中執行多重匹配查找的最有效方法?

aDictionary= {"key":["value", "value2", ... 

rests = \ 
     list(map((lambda key: Resp(key=key)), 
        [key for key, values in 
         aDictionary.items() if (test1 in values or test2 in values)])) 

使用python3。願意儘可能多地記住它。

考慮拋出兩個字典查找單獨的進程加速(這是否有道理?)。任何其他的優化想法表示歡迎


  • 值絕對可以排序,變成了集;它是預先計算的,非常大。
  • 總是LEN(值)>>>> LEN(測試),雖然他們倆都隨着時間而長勢
  • LEN(測試)的生長速度非常非常慢,並有新的價值觀每次執行
  • 目前正在研究字符串(考慮做一個與字符串>整數的映射)
+0

最終會有兩個以上的'testx'嗎?這對於是否從列表中刪除列表會有一些影響。另外,'testx'值是否經常出現在'values'中,或者很少出現? '價值'會被分類嗎? – schwobaseggl

+0

'values'會被排序嗎?平均而言,每個關鍵字有多少'testx'變量? – schwobaseggl

+1

你有多少其他方法被淘汰,因爲不盡如人意 - 所以我們可以避免重複勞動。 – wwii

回答

2

對於初學者來說,沒有任何理由,當你已經在使用列表解析使用map,這樣你就可以刪除,以及外list電話:

rests = [Resp(key=key) for key, values in aDictionary.items() 
     if (test1 in values or test2 in values)] 

第二種可能的優化可能是將每個值列表轉換爲一個集合。這會花費最初的時間,但它會改變你的查詢(in使用)從線性時間到不變時間。您可能需要爲此創建一個單獨的輔助函數。喜歡的東西:

def anyIn(checking, checkingAgainst): 
    checkingAgainst = set(checkingAgainst) 
    for val in checking: 
     if val in checkingAgainst: 
      return True 
    return False 

然後你可以改變你的列表中理解的末尾改爲

...if anyIn([test1, test2], values)] 

但同樣,這可能只會是值得的,如果你有你檢查兩個以上的值,或者如果values中的值列表非常長。

2

如果tests有足夠多,自然會還清切換到設置操作:

tests = set([test1, test2, ...]) 
resps = map(Resp, (k for k, values in dic.items() if not tests.isdisjoint(values))) 
# resps this is a lazy iterable, not a list, and it uses a 
# generator inside, thus saving the overhead of building 
# the inner list. 

開啓dict值成組將不會獲得任何東西作爲轉換將O(N)N是增加的大小的所有values列表中,而上述不相交操作將僅迭代每個values,直到遇到testxO(1)查找。

map如果您不需要使用lambda,則可能比理解更高效。如果key可以用作Resp__init__中的第一個位置參數,但肯定不會與lambda! (Python List Comprehension Vs. Map)。否則,生成器或理解將會更好:

resps = (Resp(key=k) for k, values in dic.items() if not tests.isdisjoint(values)) 
#resps = [Resp(key=k) for k, values in dic.items() if not tests.isdisjoint(values)] 
+0

如果不是tests.isdisjoint(set(values))過濾器''''或者'''如果不是tests.isdisjoint(values)'''? – wwii

+0

我可以預先將這些值預先轉換成一個集合。設置轉換的關鍵可能不值得,因爲它可能在運行時 – blueberryfields

+0

@wwii這會提高性能,但前提是你可以從一開始就設置「值」集。否則,轉換'list'-'set'會超過收益。 – schwobaseggl

相關問題