2013-06-02 50 views
3

檢查Python中的dict對象內是否存在屬性集合的好方法是什麼?檢查在Python中的dict對象內是否存在屬性集合

目前,我們正在這樣做,但似乎有可能是一個更好的辦法:

properties_to_check_for = ['name', 'date', 'birth'] 
for property in properties_to_check_for: 
    if property not in dict_obj or dict_obj[property] is None: 
     return False 

非常感謝!

+2

你的意思'在property_to_check_for'中的屬性?另外,不要使用'property'作爲變量名稱,因爲它會覆蓋內建。 – Volatility

+3

請注意,*屬性*通常用於表示對象('spam.ham')的屬性。字典有*鍵*。正確使用術語可以更輕鬆地處理代碼。 –

+0

@Lattyware:好點。這應該是PEP20分之一;) – Tadeck

回答

8

可以使用all與發電機:

all(key in dict_obj for key in properties_to_check_for) 

它會短路,就像你for循環。這是你的當前代碼的直接翻譯:

all(dict_obj.get(key) is not None for key in properties_to_check_for) 

d.get(key)將返回None如果關鍵是不是在你的字典,所以你並不真的需要檢查它是否在那裏事前。

+1

+1。 'all()'是做這件事的最簡單方法,'dict.get()'也是最好的解決方案。另外,如果您不知道發生器表達式,[這裏](http://www.youtube.com/watch?v=pShL9DCSIUw)是一個視頻,它與列表表單以及其他表兄弟一起解釋它們。 –

3

你可以使用any()

any(dict_obj.get(prop) is None for prop in properties_to_check_for) 

這將返回True如果任何property沒有在properties_to_check_for發現,或者如果它的值是None

+0

您的解決方案與Blender提出的解決方案完全相反。結果也會相反(當所有屬性被找到時,Blender會給出'True',否則'False'會給出完全相反的結果)。無論如何,upvoting。 – Tadeck

+0

@Tadeck我同意,甚至指出。但是+1會轉向攪拌機,其答案完全等同於OP的代碼。 :) –

2

大型辭書對大名單進行比較,通過比較與viewkeys一個set版本的properties_to_check_for可以提供性能返回set狀物體利於

if dict_obj.viewkeys() >= set(properties_to_check_for): 

定時測量:

timeit.timeit('dict_obj.viewkeys() >= set(properties_to_check_for)', 
setup='dict_obj = dict(zip(xrange(100000), xrange(100000))); properties_to_check_for=xrange(10000)', 
number=10000) 
9.82882809638977 
timeit.timeit('all(key in dict_obj for key in properties_to_check_for)', 
setup='dict_obj =dict(zip(xrange(100000),xrange(100000)));properties_to_check_for=list(xrange(10000))', 
number=10000) 
12.362821102142334 
+0

你可以測試嗎? – Blender

+0

@Blender,測試哪個部分?上面的表達式或性能部分? – iruvar

+0

性能部分。 – Blender

相關問題