2011-08-25 49 views
2

一個關鍵考慮下面的代碼的Python:檢查是否有任何列表元素是在一本字典

all_options = { "1": "/test/1", "2": "/test/2", "3": "/test/3" } 
selected_options = [ "1", "3" ] 

如何得到all_options其中關鍵匹配selected_options條目中的條目?

我開始走上利用列表綜合的路徑,但我卡在最後一句:

final =() 
[ final.append(option) for option in all_options if ... ] 

謝謝

+1

這是使用列表解析的錯誤方法。你正在創建一個None的大名單並把它扔掉。只要用'final = [...]' –

回答

5

就這樣?

>>> dict((option, all_options[option]) for option in selected_options if option in all_options) 
{'1': '/test/1', '3': '/test/3'} 

通過Python 2.7和3起,您可以使用dict comprehension語法:

{option : all_options[option] for option in selected_options if option in all_options} 

或者,如果你只是想值:

>>> [all_options[option] for option in selected_options if option in all_options] 
['/test/1', '/test/3'] 
+0

有沒有辦法讓結果成爲字典而不是列表? –

+0

@Misha M:是的。我已經更新了我的答案。 – Johnsyweb

+0

剛剛對此發表評論:)此工作完美,謝謝 –

1
[option for option in all_options if option in selected_options] 

你可能想使一個setselected_options和使用,而不是如果有很多。

+0

這是一個繞口令! –

+1

@NullUserException:「看起來不正確」不是理由。 –

+0

嗯,我的印象是,OP想要根據Johnsyweb和我寫的內容來回答,但我可能是錯的。 – NullUserException

1

使用set(),而是和take advantage of the intersection operation

>>> final = set(all_options.keys()) & set(selected_options) 
>>> print(final) 
{'1', '3'} 

以上只返回鍵,但NullUserException指出,這個問題可能要值以及,使用字典理解中:

>>> {x: all_options[x] for x in set(all_options.keys()) & set(selected_options)} 
{'1': '/test/1', '3': '/test/3'} 

爲了完整起見,這裏的只是值:

>>> [all_options[x] for x in set(all_options.keys()) & set(select_options)] 
['/test/1', '/test/3'] 

以下錯誤。使用set()迭代這兩個列表,而不是一個。

使用套更好假設選項變大。條件列表推導檢查其中一個容器中的每個項目,但是一個交集使用Python的優秀散列。即使這裏的列表理解只在all_options中查找所需的鍵。

+1

嘿,爲什麼-1? –

+0

構建這些集合仍然需要迭代容器 - 但這是每個集合的迭代,而不是有效地遍歷笛卡爾積。 –

+0

就這樣。沒有這樣想過。儘管如此,-1之前我說過。 –

0

我不知道它確切你試圖返回的內容,所以我給一對夫婦的選擇:

如果你試圖返回:「1」,「3」]

[option for option in all_options if option in selected_options] 

OR

,如果你試圖返回:[ '/測試/ 1', '/測試/ 3']

[all_options[option] for option in all_options if option in selected_options] 
1

我如何從all_options其中關鍵匹配selected_options的條目中的條目?

有了理解。我們有兩種:列表理解和生成器理解。

注意,這取決於你所說的「項」的內容。如果你想要一個dict的鍵/值對匹配,那麼你需要一個理解來創建鍵/值對,然後通過將它提供給dict構造函數來創建一個字典。

有一個特殊的語法規則,說如果我們只用一個參數調用可調用的東西(比如說一個類構造函數),並且該參數是一個生成器理解,那麼我們只需要一對括號(而不是二:一個調用函數,另一個將理解標記爲理解)。這讓我們寫出非常自然的東西。

在另一方面,如果你只是想鍵的list,那麼你可以只用一個列表理解。 (你可以通過一臺發電機理解爲list構造,太。)

我開始走上使用列表理解的路徑...

你有錯誤的觀念,從根本上,有關如何他們工作。你不用它們重複執行一個動作;你用它們重複計算結果。你不會在聲明的第一部分進行append調用,因爲(a)理解已經在爲你構建序列,所以沒有理由創建另一個空序列來追加; (b)在追加後append調用返回None,所以你最終得到一個你隨後拋棄的無值的列表。

列表解析產生一個值。生成器理解也創建一個值,但它是一個生成器(所以你必須提取它的值來使用它們)。

那麼,我們該如何寫代碼?

鍵的list看起來是這樣的:在dict迭代一個dict迭代其鍵)每個鍵,我們想要一個鍵(無修改),只要關鍵是在我們的其他list 。那就是,我們想要[key for key in all_options if key in selected_options]。這正是你如何用Python編寫的。一種語言很難自然地閱讀而仍然毫無疑義。

一個鍵值對的dict看起來是這樣的:在dict的鍵值對每個鍵值對,我們要的是對,只有關鍵是在我們的其他list。我們想要使用這些鍵值對創建一個dict,所以我們將理解包含在dict構造函數中。爲了從字典中獲得鍵值對,我們遍歷其.items()。所以,我們想要一個dict構造從一個鍵和值,對於原始dict的項目中的每個鍵和值,其中密鑰在另一個list中。再次,這正是我們寫的:dict((key, value) for (key, value) in all_options if key in selected_options)

在更新版本的Python中,我們也可以使用「詞典理解」,它基本上是語法糖,因此我們可以編寫看起來更像列表理解的東西。

+0

感謝您的解釋,現在更有意義。 –

相關問題