2012-08-15 57 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

相关问题