Suppose,
var = ('x', 3)
How to check if a variable is a tuple with only two elements, first being a type str and the other a type int in python? Can we do this using only one check? I want to avoid this -
if isinstance(var, tuple):
if isinstance (var[0], str) and (var[1], int):
return True
return False
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
来源:https://stackoverflow.com/questions/32770725/how-to-check-a-specific-type-of-tuple-or-list