Skip to content Skip to sidebar Skip to footer

Elegant Way To Check If A List Contains Int, Str, Tuple And Sub-list

I wrote some script, but I have to add some condition; the user puts a list and it must contain at least one of these types (tuple, int,s tr and sub-list). Is there an elegant way

Solution 1:

You can use a tuple of different types with isinstance:

>>> isinstance('a', (str, list, tuple, int))
True

Combine with any

>>>data = [1, 'a', (2, 4, 6)]>>>any(isinstance(x, (str, list, tuple, int)) for x in data)
True

or, if you want to do something with the objects of one these types:

for x in data:
    ifisinstance(x, (str, list, tuple, int)):
        print('found')

Solution 2:

You could add a helper function "has":

defhas(items, t):
    for item in items:
        ifisinstance(item, t):
            returnTruereturnFalsedefcheck(items):
    return has(items, int)   and has(items, str) \
       and has(items, tuple) and has(items, list)

If you want to be more compact (but less readable), use "any" and "all":

defhas(item, t):
     returnany([isinstance(items, t) for item in items])

defcheck(items):
     returnall([has(items, t) for t in (str, int, tuple, list)])

Solution 3:

You may use builtin any function. Quoting docs:

any(iterable)

Return True if any element of the iterable is true. If the iterable is empty, return False.

Sample usage:

expected_types = {int, str, tuple, list}  # set of expected typesfor i in seq:
    ifany(isinstance(i, t) for t in expected_types):
        pass# do something

To check all elements of sequence you may use built-in all function. So, to check all elements of sequence you may simply use:

expected_types = {int, str, tuple, list}
ifall(any(isinstance(i, t) for t in expected_types) for i in seq):
    pass# condition is sufficient

Both all() and any() performs short-circuiting, so operation has reasonable performance. If you don't care about subclasses you may check type - it speeds up isinstance(i, t) for t in expected_types from O(n) to O(1).

expected_types = {int, str, tuple, list}
ifall(type(i) in expected_types for i in seq):
    pass# condition is sufficient, but not for subclasses of int, str, tuple or list

All checks above tests if all objects are instances of one of expected_types, but not if all types occurs in sequence. If you want to ensure "at least one of each type" condition you may use collections.Counter.

c = collections.Counter(type(o) for o in seq)
ifall(c[t] >= 1for t in {int, list, tuple, str}):
    pass# seq contains at least one of each type

Solution 4:

To get the type of an object, you can use the built-in type() function. Passing an object as the only parameter will return the type object of that object:

 eg:
    a=5
    type(a) will return'int'

Solution 5:

Use built-in all and any:

all([any(lambda x: isInstance(x,i), lst_to_check) for i in instances_list])

Post a Comment for "Elegant Way To Check If A List Contains Int, Str, Tuple And Sub-list"