How to check a specific type of tuple or list?

走远了吗. 提交于 2019-12-06 09:42:00

Here's a simple one-liner:

isinstance(v, tuple) and list(map(type, v)) == [str, int]

Try it out:

>>> def check(v):
        return isinstance(v, tuple) and list(map(type, v)) == [str, int]
...
>>> check(0)
False
>>> check(('x', 3, 4))
False
>>> check((3, 4))
False
>>> check(['x', 3])
False
>>> check(('x', 3))
True

Well considering tuples are variable in length you're not going to find a method that checks this instance of all it's types. What's wrong with the method you have? It's clear what it does and it fits your usage. You're not going to find a pretty one liner AFAIK.

And you do have a one liner... Technically:

def isMyTuple(my_tuple):
    return isinstance(my_tuple,(tuple, list)) and isinstance(my_tuple[0],str) and isinstance(my_tuple[1],int)

var = ('x', 3)

print isMyTuple(var)

If you're going to do this check many times, calling the method is DRY!

Not exactly what you ask for, but you might find it useful.

from itertools import izip_longest


def typemap(iterable, types, *indexes):
    # izip_longest helps with the length check, because we will get a TypeError if len(iterable) > len(types)
    try:
        _iterable = ((elem for ind, elem in enumerate(iterable)
                     if ind in indexes) if indexes else iterable)
        return all(isinstance(elem, _type)
                   for elem, _type in izip_longest(_iterable, types))
    except TypeError:
        return False

typemap((1, 2, "ch", {}, []), (int, int, str, dict, list)) # -> True
typemap((1, 2, "ch", {}, []), (int, int, str, dict)) # -> False
typemap((1, 2, "ch", {}, []), (int, int, str, list), 0, 1, 2, 4) # -> True

You can chain all your ifs on one line:

result = isinstance(var, tuple) and isinstance(var[0], str) and isinstance(var[1], int)

result will be True is all conditions match, else it'll be False

You can pass a tuple of arguments to isinstance to test for a list or a tuple:

def test(t):
    return  isinstance(t, (tuple, list))and len(t) == 2 and\
        isinstance(t[0], str) and isinstance(t[1], int)

If you only want to accept either lists or tuples with two elements you need the check for the length, if it did not have to be 2 you would still need to make sure it had at least two elements to avoid an indexError

You could go down the route of begging forgiveness:

def isMyTuple( var):
    try:
        return isinstance(var, tuple) and \
               isinstance (var[0], str) and \
               isinstance(var[1], int)
    except:
        return False

I'm not entirely certain you need the try ... except in this case. Python uses short-circult logic. If it's not a tuple the second and third tests don't get executed and so you don't crash out trying to index a non-indexable var. But just possibly, someone derived a class from Tuple and modified it so its indexes aren't integers, or some other wierdness.

BTW should you should also check len(var)==2 ?

You can write your own function that checks if a variable matches a specification:

def istype(var, spec):
    if type(var) != type(spec):
        return False
    if isinstance(spec, tuple):
        if len(var) != len(spec):
            return False
        return all([istype(var[i], spec[i]) for i in range(len(var))])
    return True

You have to add more checks for other types, but for your example this will suffice.

>>> istype((1,'x'), (2,'y'))
True
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!