如何检查列表中包含的类型?

use*_*358 2 python error-reporting

我想在不定义函数的情况下执行以下操作:

if isinstance(x,(list,tuple)) and every_element_isinstance(x,basestring):
   foobar
Run Code Online (Sandbox Code Playgroud)

即: implementing type checking

这是一个简写builtin吗?

Vol*_*ity 9

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

if isinstance(x, (list, tuple)) and all(isinstance(i, basestring) for i in x):
    #do whatever
Run Code Online (Sandbox Code Playgroud)

  • 没有任何列表理解`([... for ...])`的这种解决方案在慢速条件下更好,因为即使第一个条件不满足,列表理解也会评估所有条件. (3认同)

Brt*_*rtH 5

if isinstance(x, (list, tuple)) and all([isinstance(i, basestring) for i in x]):
    foobar
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,列表理解[ ... ]在这里比没有列表理解更快,包括短列表和长列表:

短名单:

>>> 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
Run Code Online (Sandbox Code Playgroud)

长名单:

>>> 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
Run Code Online (Sandbox Code Playgroud)


mik*_*iku 5

没有内置定义泛型类型。但是有很多验证库可以模仿这个功能。

使用https://github.com/alectomas/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
Run Code Online (Sandbox Code Playgroud)

几天前,这个库中添加对元组的支持

>>> s_tuple = voluptuous.Schema((basestring, ))
Run Code Online (Sandbox Code Playgroud)

现在将两者结合起来得到你的结果:

>>> from voluptuous import any

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

double- 甚至更快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
Run Code Online (Sandbox Code Playgroud)