Python AND operator on two boolean lists - how?

前端 未结 9 2081
感动是毒
感动是毒 2020-11-28 09:36

I have two boolean lists, e.g.,

x=[True,True,False,False]
y=[True,False,True,False]

I want to AND these lists together, with the expected o

相关标签:
9条回答
  • 2020-11-28 10:30

    Instead of using

    [a and b for a, b in zip(x, y)]
    

    one could just use the possibility of numpy to multiply bool-values:

    (np.array(x)*np.array(y))
    >> array([ True, False, False, False], dtype=bool)
    

    Or do I overlook a special case?

    0 讨论(0)
  • 2020-11-28 10:32

    In addition to what @Martijn Pieters has answered, I would just add the following code to explain and and or operations in action.

    and returns the first falsy value encountered else the last evaluated argument.

    Similarly or returns the first truthy value encountered else the last evaluated argument.

    nl1 = [3,3,3,3,0,0,0,0]
    nl2 = [2,2,0,0,2,2,0,0]
    nl3 = [1,0,1,0,1,0,1,0]
    and_list = [a and b and c for a,b,c in zip(nl1,nl2,nl3)]
    or_list = [a or b or c for a,b,c in zip(nl1,nl2,nl3)]
    

    Values are

    and_list = [1, 0, 0, 0, 0, 0, 0, 0]

    or_list = [3, 3, 3, 3, 2, 2, 1, 0]

    0 讨论(0)
  • 2020-11-28 10:33

    Thanks for the answer @Martijn Pieters and @Tony. I dig into the timing of the various options we have to make the AND of two lists and I would like to share my results, because I found them interesting.

    Despite liking a lot the pythonic way [a and b for a,b in zip(x,y) ], turns out really slow. I compare with a integer product of arrays (1*(array of bool)) * (1*(array of bool)) and it turns out to be more than 10x faster

    import time
    import numpy as np
    array_to_filter = np.linspace(1,1000000,1000000)                # 1 million of integers :-)
    value_limit = 100
    cycles = 100
    
    # METHOD #1:  [a and b for a,b in zip(x,y) ]
    t0=time.clock()
    for jj in range(cycles):
        x = array_to_filter<np.max(array_to_filter)-value_limit   # filter the values > MAX-value_limit
        y = array_to_filter>value_limit                          # filter the values < value_limit
        z= [a and b for a,b in zip(x,y) ]                       # AND
        filtered = array_to_filter[z]
    print('METHOD #1 = %.2f s' % ( (time.clock()-t0)))
    
    
    
    # METHOD 1*(array of bool) AND  1*(array of bool)
    t0=time.clock()
    for jj in range(cycles):
        x = 1*(array_to_filter<np.max(array_to_filter)-value_limit)   # filter the values > MAX-value_limit
        y = 1*(array_to_filter>value_limit)                          # filter the values < value_limit
        z = x*y                                                     # AND
        z = z.astype(bool)                                          # convert back to array of bool
        filtered = array_to_filter[z]
    print('METHOD #2 = %.2f s' % ( (time.clock()-t0)))
    

    The results are

    METHOD #1 = 15.36 s
    METHOD #2 = 1.85 s
    

    The speed is almost affected equally by the size of the array or by the number of cycles.
    I hope I helped someone code to be faster. :-)

    0 讨论(0)
提交回复
热议问题