2016-11-10 82 views
0

我有一個簡單的字典大看起來像這樣:比較字典值和彈出鍵

my_dict = {'a': [-33.27, -2.12, 5.23], 'b': [-57.11, 9.82, -26.13], ...}

所以鍵是字符串和值浮動的名單。

我想要做的是通過運行一個標準,找到並刪除一些冗餘鍵:值對減少它的大小。

僞代碼的標準是:

每個鍵的我,發現在字典中是否存在不同的J鍵,以便:

  • value_of_key_i[0] > value_of_key_j[0] and
  • value_of_key_i[1] > value_of_key_j[1] and
  • abs(value_of_key_i[2]) < abs(value_of_key_j[2])

我寫的任務是這樣的:

to_remove = [] 
for ilcs, iloads in running_load.items(): 
    for jlcs, jloads in running_load.items(): 
     if iloads[0] > jloads[0] and iloads[1] > jloads[1] and abs(iloads[2]) < abs(jloads[2]): 
      # print(iloads, jloads) 
      to_remove.append(ilcs) 
      break 

for i in to_remove: 
    running_load.pop(i) 

它的工作,但明確地遍歷字典兩次,必要的額外的for循環的膨化感覺效率不高..

是否有更好的方法?用發電機做這件事效率會更高嗎,比方說,any()

PS:我的方法的另一個問題是,它不能測試平等,因爲在某些點的值將要對自己進行測試(是一個可以檢查該和continue但是......)

+0

您可能會從這些值上對'load.items()'進行排序以便避免查看您知道不符合條件的列表 –

+0

好點,但實際上我需要它們以該順序。我無法對價值進行排序。但是也許我可以使用'ordereddict',讓我們說'values [0]'並且只搜索當前鍵的infront。 –

+0

你想要什麼順序的值?不能保證它們會像字典一樣出現在字典中。 –

回答

0

您可以創建一個新字典,並在其中添加將保留的元素,而不是使用要刪除的元素列表。

我真的沒有看到一種方法來減少初始階段的O(n^2)複雜性(比較每個元素與其他元素),但是如上所述,排序會幫助一些。

此外,我想你會生成兩個不同的列表,其中包含來自詞典中的項目的相同內容(每個列表中有一個列表)。與「比較每個項目與其他項目」相比,這應該不算太多,但它仍然有幫助。

0

因此沿着最初也可能是最明顯的解決方案(algo1)我寫的第二個(ALGO2)認爲:

  • 創建從字典元組的列表。
  • 命令它(從而減少比較到2)。
  • 切片它(從而減少比較從N^2到(n^2 + N)/ 2 - >越大n時,更大的優點)在同一迴路
  • 和彈出。

def algo1(a_dict): 
    to_remove = [] 
    for ilcs, iloads in a_dict.items(): 
     for jlcs, jloads in a_dict.items(): 
      if iloads[0] > jloads[0] and iloads[1] > jloads[1] and abs(iloads[2]) < abs(jloads[2]): 
       # print(iloads, jloads) 
       to_remove.append(ilcs) 
       break 
    for i in to_remove: 
     a_dict.pop(i) 
    return a_dict 

def algo2(a_dict): 
    ordered_list_view = sorted(a_dict.items(), key=lambda t: abs(t[1][2])) 
    for i, ikv in enumerate(ordered_list_view): 
     forward_slice = ordered_list_view[i:] 
     for j, jkv in enumerate(forward_slice): 
      if all(ikv[1][j] > jkv[1][j] for j in range(2)): 
       print(ikv[1], jkv[1]) 
       a_dict.pop(ikv[0]) 
       break 
    return a_dict 

我計時他們太多,但讓我吃驚,algo1仍然較快。儘管如此,但仍然..