2015-04-08 65 views
3

我有一本字典:避免重複插入到Python列表與理解

XY_dict = {1: [(12, 55),(13, 55)], 
2: [(14, 55),(15, 57)], 
3: [(14, 55),(15, 58)], 
4: [(14, 55),(16, 55)]} 

我想找出哪些鍵有值的元組,其中是唯一的(不存在於任何其他鍵的值)。從示例字典中,密鑰1是唯一的,因爲任何其他字典的密鑰中都不存在(12, 55)(13, 55)。通過獲取具有共享值的密鑰列表,我可以稍後反轉結果並獲取唯一的密鑰。

我使用列表理解爲獲得鍵與共同的價值觀:

keys_shared_values = [k1 for k1,v1 in XY_dict.iteritems() 
         for k,v in XY_dict.iteritems() 
         for XY_pair in v 
         if XY_pair in v1 and k != k1 and k1 not in keys_shared_values] 

其結果是,我越來越[2, 2, 3, 3, 4, 4]但我希望重複不被插入(因爲我評估鍵值是否爲在結果列表中)。我可以通過運行list(set(shared_values))來解決這個問題,但想知道我的代碼有什麼問題。

+1

什麼是'key_shared_values',在'如果XY_pair在V1和k!=不key_shared_values' K1,K1的? – thefourtheye

+0

@thefourtheye,感謝評論。我期望這是'[2,3,4]'。 –

+1

你總是可以使用set的理解,比如'key_shared_values = list({k1 for k1,v1在XY_dict.iteritems()for k,v在XY_dict.iteritems()for XY_pair in v})'如果你還想使用理解。 – Geekfish

回答

1

問題是,keys_shared_values是空的,直到你完成理解,所以你的k1 not in keys_shared_values將永遠返回True。你不能引用當前的理解。您最好的選擇是按照您的建議轉換爲set

keys_shared_values = [] 
for k, v in XY_dict.iteritems(): 
    for k1, v1 in XY_dict.iteritems(): 
     for XY_pair in v: 
      if XY_pair in v1 and k != k1 and k1 not in keys_shared_values: 
       keys_shared_values.append(k1) 
print keys_shared_values 

結果:

你應該,如果你想要的功能,你的代碼變更爲循環

[3, 4, 2] 
+0

感謝您指出了這一點。使用for循環進行這項工作是我一直在做的事情,但是希望使它成爲列表理解。現在我知道問題是什麼。 –

1

因爲key_shared_values沒有定義你的代碼不能正常工作。如果你清理你的環境,你會看到如果你嘗試運行你的例子,你會得到一個NameError: name 'key_shared_values' is not defined錯誤。

這是因爲keys_shared_values直到理解語句運行才真正定義,所以在理解中不能真正引用它,因爲它不存在。

如果您要預先定義它,例如keys_shared_values = []那麼這仍然不起作用,因爲每次您在理解中引用它時都會引用原始空列表值。理解執行時,它不會動態更改keys_shared_values的值,而是在內存中創建列表,然後將其分配給keys_shared_values

3

其他人已經解釋了你的列表理解有什麼問題。以下是另一種方法,使用Counter字典來計算不同xy對的出現頻率,並使用它來過濾詞典中的唯一條目。

>>> from collections import Counter 
>>> c = Counter(xy for v in XY_dict.values() for xy in v) 
>>> {k: v for k, v in XY_dict.iteritems() if all(c[xy] == 1 for xy in v)} 
{1: [(12, 55), (13, 55)]} 

還是要拿到鑰匙有共同的價值觀:

>>> [k for k, v in XY_dict.iteritems() if any(c[xy] > 1 for xy in v)] 
[2, 3, 4] 

注意,這也更有效,因爲你從字典比較的兩個項目每個組合,給你二次複雜性,而這種方法具有線性複雜性。

+0

非常感謝。這絕對快得多;櫃檯似乎是非常酷的功能,我可以使用更多。 –