Python Forum

Full Version: code pattern to test if list has all the same
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
hey all beginners (newbies). this is for you.

this is so simple, coding a function to do it is not worth it. this code checks to see if all the items in the list named foo are floats. you can the figure out how to test for other types:
    if min([isinstance(x,float) for x in foo]):
this works because the min() builtin function works with booleans, treating False as lower in value than True. you can therefore do other conditions spanning a list or tuple or set. it also works on dictionaries, testing the keys. so here, we test if all the items in the list named foo are equal to the string 'py2' or 'py3'
    if min([x in ('py2','py3') for x in foo])
enjoy
Or you could just use all.

if all([isinstance(x, float) for x in foo]):
is all better in some way, like being faster?

all handles an empty list by returning True, which would be the wrong thing in my current projects. min throws an exception. either way i still need to test the list for empty before applying either logic test so i can make sure the correct action is performed.
(Jul-25-2018, 04:10 AM)Skaperen Wrote: [ -> ]is all better in some way, like being faster?

all() stops at first occurance of False but min() have to go through all list elements. So it can be said that all() is faster.

If performance is a consideration then generator comprehension could be a choice:

if all(isinstance(x, float) for x in foo):
List will not be created, instead values are returned one at the time and at first False code stops.
yes, that does make all() statically faster and the choice for speed. i can see how it behave for an empty list, now. it sets some variable to True and looks for the first False. if none found, it leaves it as True which might be the answer needed in dome cases. and if not, just test for empty first. an empty list comes across as False as a boolean.
(Jul-25-2018, 04:10 AM)Skaperen Wrote: [ -> ]all handles an empty list by returning True, which would be the wrong thing in my current projects.
foo = []
if foo and all(isinstance(x, float) for x in foo):
    print('all float')
else:
    print('some problem')
Output:
some problem
just for completeness - there is also any() - Return True if any element of the iterable is true. If the iterable is empty, return False.
also you can 'extend' all() it in your own helper function
def nonempty_alltypes(iterable, check_types):
    """Check that iterable is not empty and all elements are one of check_types. Returns bool."""

    return all((iterable, all(isinstance(x, check_types) for x in iterable)))


test_list = [[1,2], [], [1, 3, 'a']]
test_for = int

for test_item in test_list:
    print('{} | {} --> {}'.format(test_item, test_for, nonempty_alltypes(test_item, test_for)))

test_item = [1, 2, 4.5]
test_for = (int, float)
print('{} | {} --> {}'.format(test_item, test_for, nonempty_alltypes(test_item, test_for)))
Output:
[1, 2] | <class 'int'> --> True [] | <class 'int'> --> False [1, 3, 'a'] | <class 'int'> --> False [1, 2, 4.5] | (<class 'int'>, <class 'float'>) --> True