The smart any () function to check if at least n elements are True?

Say I have an iterative (in my case list):

l = [True, False, False, True]

I know that the easiest and fastest way to check if at least one of these elements is True is to simply use any(l)which will return True.

But what if I want to check that there are at least two elements True? My goal is to process it in the fastest way.

My code now looks like this (for two elements):

def check_filter(l):
    if len([i for i in filter(None, l)]) > 1:
        return True
return False

This is about 10 times slower than any(), and for me, it is not very similar to pythonic.

+4
source share
4 answers

, any True n -times:

def check(it, num):
    it = iter(it)
    return all(any(it) for _ in range(num))

>>> check([1, 1, 0], 2)
True

>>> check([1, 1, 0], 3)
False

, , , any , . all, , any False.

, , . .


, map itertools.repeat :

from itertools import repeat

def check_map(it, num):
    return all(map(any, repeat(iter(it), num)))

:

# Second "True" element is in the last place
lst = [1] + [0]*1000 + [1]

%timeit check_map(lst, 2)  # 10000 loops, best of 3: 20.3 µs per loop
%timeit check(lst, 2)      # 10000 loops, best of 3: 23.5 µs per loop
%timeit many(lst, 2)       # 10000 loops, best of 3: 153 µs per loop
%timeit sum(l) >= 2        # 100000 loops, best of 3: 19.6 µs per loop

# Second "True" element is the second item in the iterable
lst = [1, 1] + [0]*1000

%timeit check_map(lst, 2)  # 100000 loops, best of 3: 3.05 µs per loop
%timeit check(lst, 2)      # 100000 loops, best of 3: 6.39 µs per loop
%timeit many(lst, 2)       # 100000 loops, best of 3: 5.02 µs per loop
%timeit sum(lst) >= 2      # 10000 loops, best of 3: 19.5 µs per loop
+11
L = [True, False, False, True]

:

def many(iterable, n):
    if n < 1:
        return True
    counter = 0
    for x in iterable:
        if x:
            counter += 1
            if counter == n:
                return True
    return False

:

>>> many(L, 2)
True
+4

sum:

sum(l) >= 2
# True
+1

Presumably anygoes through an iteration until it finds an element True, and then stops.

Your solution scans all the elements to see if there is at least 2. Instead, it should stop scanning as soon as it finds the second element True.

0
source

Source: https://habr.com/ru/post/1671064/


All Articles