How to check to make sure all items in a list are of a certain type

Viewed 1466

I want to enforce that all items in a list are of type x. What would be the best way to do this? Currently I am doing an assert like the following:

a = [1,2,3,4,5]
assert len(a) == len([i for i in a if isinstance(i, int)])

Where int is the type I'm trying to enforce here. Is there a better way to do this?

5 Answers

I think you are making it a little too complex. You can just use all():

a = [1,2,3,4,5]
assert all(isinstance(i, int) for i in a)

a = [1,2,3,4,5.5]
assert all(isinstance(i, int) for i in a)
# AssertionError

You need to decide whether you are interested in also including any subclass of int. isinstance(i, int) will return True if i is True or False because bool is a subclass of int.

Whatever you do, you should certainly use all as Mark Meyer suggests. (And incidentally, one advantage of doing that over what you are doing with len is that if any fail the test then it doesn't needlessly check the remaining items, provided that you are using a generator and not building a list of results -- the fact that no [...] symbols used anywhere in the syntax gives a clue that this is the case.)

But if you are only interested in including actual int type itself, then you should do:

assert all(type(i) is int for i in a)

(If you do want to allow e.g. bool, then see Mark Meyer's answer.)

If you expect the assertion to succeed most of the time, which I believe is the case as an enforcement in the real world, mapping items in the list to the type function and constructing a set with the output and asserting that it is equal to a set of type int would be faster than using all since the iterations are performed in C.

assert set(map(type, a)) == {int}

See timing demo: https://repl.it/@blhsing/AstonishingGivingVirtualmachines

In Python you need ro ask yourself if it is necessary? Normally you check data going in to a program, then rely on your programs structure to distribute appropriate types within itself. You could use Mypy and type annotations to help (statically). You could make runtime checks optional - part of a debug mode, for example. In the past I have had to go out to the level of interacting systems where data checkers used in learning the system were then turned off and only used in debug. Other programs could have less costly checks, internal development would use the checkers, and third party code could have the checkers run on their releases. Data checking took time and I had to look for efficient solutions.

You can use all(), very simple but powerful

a = [1,2,3,4,5]
assert all(isinstance(i, int) for i in a)
Related