Best way to check if an item is present in a list of lists?

I have example list like this:

example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg']]

Now, I check if it has empty string like this:

has_empty = False;
for list1 in example_list:
    for val1 in list1:
        if val1 == '':
            has_empty = True

print(has_empty)

This works OK as it prints True, but looking for more pythonik method?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You can use itertools.chain.from_iterable:

>>> from itertools import chain
>>> example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg']]
>>> '' in chain.from_iterable(example_list)
True

Just in case if the inner lists are bigger(more than 100 items) then using any with a generator will be faster than the above example because then the speed penalty of using a Python for-loop is compensated by the fast in-operation:

>>> any('' in x for x in example_list)
True

Timing comparisons:

>>> example_list = [['aaa']*1000, ['fff', 'gg']*1000, ['gg']*1000]*10000 + [['']*1000]
>>> %timeit '' in chain.from_iterable(example_list)
1 loops, best of 3: 706 ms per loop
>>> %timeit any('' in x for x in example_list)
1 loops, best of 3: 417 ms per loop

# With smaller inner lists for-loop makes `any()` version little slow

>>> example_list = [['aaa'], ['fff', 'gg'], ['gg', 'kk']]*10000 + [['']]
>>> %timeit '' in chain.from_iterable(example_list)
100 loops, best of 3: 2 ms per loop
>>> %timeit any('' in x for x in example_list)
100 loops, best of 3: 2.65 ms per loop

Method 2

You can do use combination of any, map and chain:

In [19]: example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg']]

In [20]: import operator, itertools

In [21]: any(map(operator.not_, itertools.chain(*example_list)))
Out[21]: True

In [22]: example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['not empty', 'gg']]

In [23]: any(map(operator.not_, itertools.chain(*example_list)))
Out[23]: False

Method 3

Just convert the whole list to string and check for the presence of empty strings, i.e. '' or "" in it.

>>> example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg']]
>>> any(empty in str(example_list) for empty in ("''", '""'))
True
>>> example_list = [['aaa'], ['fff', 'gg'], ['ff'], [ 'gg', ''']]
>>> any(empty in str(example_list) for empty in ("''", '""'))
False

Note that this won’t work with lists which have empty string as part of the string itself – example 'hello "" world'

Another approach could be to flatten the dict and check for presence of empty strings in it

>>> example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['gg', 'hello "" world']]
>>> '' in [item for sublist in example_list for item in sublist]
False
>>> example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg', 'hello "" world']]
>>> '' in [item for sublist in example_list for item in sublist]
True

Method 4

using map and lambda:

>>> def check_empty(l):
...     k=map(lambda x: '' in x and True,l)
...     for x in k:
...         if x==True:
...             return True
...     return False
... 
>>> check_empty(example_list)
False
>>> example_list
[['aaa'], ['fff', 'gg'], ['ff'], ['gg', 'hello "" world']]
>>> example_list = [['aaa'], ['fff', 'gg',''], ['ff'], ['gg', 'hello "" world']]
>>> check_empty(example_list)
True

Method 5

example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg']]

has_empty = False

for list in example_list:

    if '' in list:
        has_empty = True
print(has_empty)


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x