2013-01-06 40 views
1

我要做到以下几点没有定义的函数:如何检查列表中包含的类型?

if isinstance(x,(list,tuple)) and every_element_isinstance(x,basestring): 
    foobar 

即:implementing type checking

是否有速记/ builtin这个?

+0

为什么你不希望定义一个函数? –

回答

8

我认为这是最好的解决方案(如果我理解这个问题)

if isinstance(x, (list, tuple)) and all(isinstance(i, basestring) for i in x): 
    #do whatever 
+3

这个解决方案没有任何列表理解'([... for ...])'对于缓慢条件更好,因为即使第一个条件不满足,列表理解也会评估所有条件。 – hynekcer

+0

'isinstance(x,collections.Iterable)'在这里可能更适合 – Eric

5
if isinstance(x, (list, tuple)) and all([isinstance(i, basestring) for i in x]): 
    foobar 

出人意料的是,与[ ... ]列表理解更快这里比一个没有,都是具有短期和长期的名单:

短名单:

>>> timeit('isinstance(x, (list, tuple)) and all(isinstance(i, basestring) for i in x)', "x=['a','b','c']") 
2.7594685942680144 
>>> timeit('isinstance(x, (list, tuple)) and all(isinstance(i, basestring) for i in x)', "x=['a','b','c']") 
2.8013695153947538 
>>> timeit('isinstance(x, (list, tuple)) and all([isinstance(i, basestring) for i in x])', "x=['a','b','c']") 
2.4351678506033068 
>>> timeit('isinstance(x, (list, tuple)) and all([isinstance(i, basestring) for i in x])', "x=['a','b','c']") 
2.4491469896721583 

长的列表:

>>> timeit('isinstance(x, (list, tuple)) and all(isinstance(i, basestring) for i in x)', "x=['a','b','c'] * 1000", number=1000) 
1.3357901657891489 
>>> timeit('isinstance(x, (list, tuple)) and all(isinstance(i, basestring) for i in x)', "x=['a','b','c'] * 1000", number=1000) 
1.3305278872818462 
>>> timeit('isinstance(x, (list, tuple)) and all([isinstance(i, basestring) for i in x])', "x=['a','b','c'] * 1000", number=1000) 
1.2626525921055531 
>>> timeit('isinstance(x, (list, tuple)) and all([isinstance(i, basestring) for i in x])', "x=['a','b','c'] * 1000", number=1000) 
1.2881240045551863 
+0

+1打我:) – Volatility

+0

@Volatility提交我的答案后一秒我看到你弹出。伟大的思想认为,我猜:D – BrtH

+0

哪一个我应该aceept呢?我的意思是两者完美 – user1358

3

有没有内置定义generic types。但有a lot of validation libraries,它可以模仿此功能。

示例使用https://github.com/alecthomas/voluptuous

>>> from voluptuous import Schema 
>>> s_list = Schema([basestring]) # only strings in a list are allowed 
>>> s_list("hello") 
... 
voluptuous.InvalidList: expected a list 
>>> s_list([123]) 
... 
voluptuous.InvalidList: invalid list value @ data[0] 
>>> s_list(["correct"]) 
["correct"] # returns the object, if validation was successful 

前几天,support for tuple was added到该库:

>>> s_tuple = voluptuous.Schema((basestring,)) 

现在将二者结合起来,让您的结果:

>>> from voluptuous import any 

# - this is now equivalent to your code 
# - raises Exceptions on invalid input 
>>> schema = Schema(any(s_list, s_tuple)) 

它甚至稍微快一点,即双倍isinstance

>>> from timeit import timeit 

>>> timeit('(schema(i) for i in x)', "x=['a','b','c']") 
0.679318904876709 

>>> timeit(""" 
     (isinstance(x, (list, tuple)) 
     and all(isinstance(i, basestring)) for i in x)""", "x=['a','b','c']") 
0.7801780700683594 
0

随着妖娆“0.8.7”您可以从miku更新的答案,跳过“元组的一部分”:

>>> from voluptuous import Schema 
>>> from timeit import timeit 
>>> s_list = Schema([basestring]) # only strings in a list are allowed 
>>> timeit('(s_list(i) for i in x)', "x=['a','b','c']") 
0.503572940826416 
>>> timeit("(isinstance(x, (list, tuple)) and all(isinstance(i, basestring)) for i in x)", "x=['a','b','c']") 
0.5400209426879883 
相关问题