4

I have come from a matlab background to python and i am just wondering if there is a simple operator in python that will perform the following function:

a = [1, 0, 0, 1, 0, 0]
b = [0, 1, 0, 1, 0, 1]
c = a|b
print c
[1, 1, 0, 1, 0, 1]

or would i have to write a separate function to do that?

guskenny83
  • 1,321
  • 14
  • 27

6 Answers6

6

You could use a list comprehension. Use izip from itertools if you're using Python 2.

c = [x | y for x, y in zip(a, b)]

Alternatively, @georg pointed out in a comment that you can import the bitwise or operator and use it with map. This is only slightly faster than the list comprehension. map doesn't need wrapped with list() in Python 2.

import operator
c = list(map(operator.or_, a, b))

Performance

List comprehension:

$ python -m timeit -s "a = [1, 0, 0, 1, 0, 0]; b = [0, 1, 0, 1, 0, 1]" \
> "[x | y for x, y in zip(a, b)]"

1000000 loops, best of 3: 1.41 usec per loop

Map:

$ python -m timeit -s "a = [1, 0, 0, 1, 0, 0]; b = [0, 1, 0, 1, 0, 1]; \
> from operator import or_" "list(map(or_, a, b))"
1000000 loops, best of 3: 1.31 usec per loop

NumPy

$ python -m timeit -s "import numpy; a = [1, 0, 0, 1, 0, 0]; \
> b = [0, 1, 0, 1, 0, 1]" "na = numpy.array(a); nb = numpy.array(b); na | nb"

100000 loops, best of 3: 6.07 usec per loop

NumPy (where a and b have already been converted to numpy arrays):

$ python -m timeit -s "import numpy; a = numpy.array([1, 0, 0, 1, 0, 0]); \
> b = numpy.array([0, 1, 0, 1, 0, 1])" "a | b"

1000000 loops, best of 3: 1.1 usec per loop

Conclusion: Unless you need NumPy for other operations, it's not worth the conversion.

Community
  • 1
  • 1
RazerM
  • 5,128
  • 2
  • 25
  • 34
4

If your data was in numpy arrays then yes this would work:

In [42]:

a = np.array([1, 0, 0, 1, 0, 0])
b = np.array([0, 1, 0, 1, 0, 1])
c = a|b
print(c)
[1 1 0 1 0 1]
Out[42]:
[1, 1, 0, 1, 0, 1]
EdChum
  • 376,765
  • 198
  • 813
  • 562
  • okay, thanks for that. so it won't work in standard arrays then? – guskenny83 Mar 25 '15 at 09:21
  • Not for a list using your notation – EdChum Mar 25 '15 at 09:23
  • Personally I think that numpy arrays are the most appropriate data structure if you're used to using arrays coming from a matlab background – EdChum Mar 25 '15 at 09:43
  • i will probably end up using numpy arrays further down the track, but i think it is a bit overkill for my current application which is literally just combining two lists of decision variables – guskenny83 Mar 25 '15 at 09:46
4

map(lambda (a,b): a|b,zip(a,b))

Itay Karo
  • 17,924
  • 4
  • 40
  • 58
  • Certainly the most pythonic way, I like the map approach :) Do you know if `map` yields better performance than using list comprehension ? – NiziL Mar 25 '15 at 09:23
  • 1
    Well, a quick and not so accurate benchmark ! `python -m timeit 'a=[0,0,0,1,0]; b=[1,0,1,1,1]; c=map(lambda (a,b): a|b, zip(a,b))'` : best of 3: 1.01 usec per loop and `python -m timeit 'a=[0,0,0,1,0]; b=[1,0,1,1,1]; c=[x|y for x,y in zip(a,b)]'`: best of 3: 0.646 usec per loop :) – NiziL Mar 25 '15 at 09:32
  • If you want `map`, it's just `map(operator.or_, a, b)` - no need for zip, map zips 'em for you. – georg Mar 25 '15 at 09:49
3

You can use numpy.bitwise_or

>>> import numpy
>>> a = [1, 0, 0, 1, 0, 0]
>>> b = [0, 1, 0, 1, 0, 1]
>>> numpy.bitwise_or(a,b)
array([1, 1, 0, 1, 0, 1])
Mazdak
  • 105,000
  • 18
  • 159
  • 188
2
c = [q|w for q,w in zip(a,b)]
print c
# [1, 1, 0, 1, 0, 1]
Aaron
  • 2,383
  • 3
  • 22
  • 53
0

I believe it can work for multiple values since zip returns a tuple

bitlist = [x & y & z for x, y, z in zip(bitlist, green_mask_h, green_mask_s)]
Omar Khan
  • 141
  • 3