Home > Mobile >  Taking bitwise '&' of arbitrary number of lists
Taking bitwise '&' of arbitrary number of lists

Time:06-01

I have an arbitrary number of lists that I want to take the boolean & of. For example for 2 lists, I have

x = [0, 1, 0, 0]
y = [1, 1, 0, 1]

[np.array(x) & np.array(y) for x,y in zip(x, y)]
[0, 1, 0, 0]

for 3 lists

z=[0,1,1,1]

I would have

[np.array(x) & np.array(y) & np.array(y) for x,y,z in zip(x, y, z)]
[0, 1, 0, 0]

etc.,

since my I have an arbitrary number of lists over which to perform this operation, what is the best method to achieve this?

CodePudding user response:

You can use zip and all:

x = [0,1,0,0]
y = [1,1,0,1]
z = [0,1,1,1]

output = [all(zipped) for zipped in zip(x, y, z)]
print(output) # [False, True, False, False]

If you do want to get [0,1,0,0] instead, use int(all(zipped)) instead of all(zipped) (but this explicit recasting is redundant in most cases).

CodePudding user response:

or using np.logical_and

x = [0, 1, 0, 1]
y = [1, 1, 0, 1]
z = [1, 1, 0, 1]

np.logical_and(x, y, z).astype(int)
array([0, 1, 0, 1])

CodePudding user response:

With map and min:

x = [0,1,0,0]
y = [1,1,0,1]
z = [0,1,1,1]

output = list(map(min, x, y, z))
print(output)

Output (Try it online!):

[0, 1, 0, 0]

Wikipedia btw even mentions using min/max for and/or.

If you have a list of lists (as "arbitrary number" suggests, since you wouldn't want to use an arbitrary number of variables), you can use list(map(min, *lists)).

CodePudding user response:

import numpy as np
import functools
import operator

x = np.array([0, 1, 0, 0])
y = np.array([1, 1, 0, 1])
z = np.array([0, 1, 1, 1])

print(functools.reduce(operator.and_, [x, y, z]))

CodePudding user response:

1 and 0 act like True and False so using product works

  lists=[x,y,z]
  np.prod(lists,axis=0)

CodePudding user response:

Since you are using numpy anyway, you can use:

np.bitwise_and.reduce(np.array([x,y,z]))

Example:

>>> x = [0, 1, 0, 0]
>>> y = [1, 1, 0, 1]
>>> z = [0, 1, 1, 1]
>>> np.bitwise_and.reduce([x, y, z])
array([0, 1, 0, 0])

But I wouldn't use numpy just for this. I'd probably go with j1-lee's answer.

Just for fun, here is another version of that answer:

>>> from functools import partial, reduce
>>> import operator as op
>>> list(map(partial(reduce, op.and_), zip(x,y,z)))
[0, 1, 0, 0]
>>>

because you are mapping a reduction operation over the zipped data

  • Related