2012-08-15 56 views
8

對於內置Python容器(listtuple,等等)in運算符相當於any(y == item for item in container)需要提醒的是前一種方法更快(漂亮):Python列表是否具有與__contains__等效的測試身份的功能?

In [13]: container = range(10000) 
In [14]: %timeit (-1 in container) 
1000 loops, best of 3: 241 us per loop 
In [15]: %timeit any(-1 == item for item in container) 
1000 loops, best of 3: 1.2 ms per loop 

是否有一個相當於any(y is item for item in container) ?也就是說,使用is而不是==的測試?

回答

6

不,沒有。 is運算符通常不需要經常證明必須維護一個C優化的方法並增加python API的混淆。

列表和元組的in測試確實做了類似於any的全搜索,雖然在C中是btw。但是,在集合中,測試使用容器底層的有效存儲算法,並且在預期的情況下搜索需要一段時間。對於集合和映射來說,密鑰都應該有一個穩定的散列,這在大多數情況下意味着不應該需要is,真的。

所以,正確的拼寫是:

# For sequences 
any(y is item for item in container) 

# For sets, short circuit first for the not-present case: 
# (note that you normally should not need this as you are supposed to rely on the hash) 
y in setcontainer and any(y is item for item in setcontainer) 

# For mappings, y is a key 
y in mapping 

# For mappings, y is a value, and you do not have a key, fall back to any 
any(y is item for item in mapping.itervalues()) 
+5

事實上,我一直認爲這是一個文檔的缺陷,方法'list.index'和'list.count'等說幾句,大意「如果沒有這樣的項目「 – mgilson 2012-08-15 14:40:28

+0

」,則返回第一個項目列表中的索引,但是即使對於集合,「in」也檢查不保證*的散列值對象是不同的。考慮'a =(1,2,3); C =(1,2,3); c是a; s = set([a]); c in s'。儘管目前我想不出一個重要的時間。 – mgilson 2012-08-15 14:47:55

+0

沒有,只是指出在set和dicts中的'in'運算符沒有* do *掃描。 – 2012-08-15 14:49:24

相關問題