Itertools Compress and Converting Bitmasks to Lists (and vice versa)¶
In [1]:
import itertools
Itertools Compress¶
Make an iterator that filters elements from data returning only those that have a corresponding element in selectors that evaluates to True.
Stops when either the data or selectors iterables has been exhausted.
In [2]:
data = 'ABCDEFG'
masklist = [1,0,0,1]
result = [x for x in itertools.compress(data,masklist)]
print(result)
If the mask has shorter length than data, then you may want the mask to be right-justified.
Especially if the mask was produced by converting an integer to a list ( 9 -> [1,0,0,1] )
In other words, you wanted the mask to look like this [0,0,0,0,1,0,0,1]
In [3]:
# perform compress after padding the mask with leading zeros
def padCompress(data,mask):
if len(mask)<len(data):
pad = [0]*(len(data)-len(mask))
mask = pad + mask
return(itertools.compress(data,mask))
data = 'ABCDEFG'
masklist = [1,0,0,1]
result = [x for x in padCompress(data,masklist)]
print(result)
In [4]:
# converting binary list to integer
# using bit shift + | operator
def list2int(binlist):
retval = 0
for bit in binlist:
retval = (retval<<1)|bit
return retval
masklist = [1,0,0,1]
x = list2int(masklist)
print(x)
In [5]:
# converting integer to binary list, we can use bin() function
s = bin(9)
print(s)
In [6]:
# get rid of the leading '0b' piece
s = bin(9)[2:]
print(s)
In [7]:
# and if you want to pad the left to a certain length
s = bin(9)[2:].zfill(8)
print(s)
In [8]:
# int2list function with optional length argument, returns a list
def int2list(num,length=0):
if length > 0:
retval = [int(i) for i in bin(num)[2:].zfill(length)]
else:
retval = [int(i) for i in bin(num)[2:]]
return retval
x = 9
list1 = int2list(x)
print(list1)
list2 = int2list(x,8)
print(list2)
In [9]:
# two more functions that might be useful: AND and OR using bitmask lists
# note that these functions use the list2int and int2list functions from above
def listOR(list1,list2):
n1 = list2int(list1)
n2 = list2int(list2)
n3 = n1|n2
list3 = int2list(n3)
return list3
def listAND(list1,list2):
n1 = list2int(list1)
n2 = list2int(list2)
n3 = n1&n2
list3 = int2list(n3)
return list3
list1 = [0,1,1,1,1,0,0,0]
list2 = [0,0,0,0,1,1,1,0]
print("OR: ",listOR(list1,list2))
print("AND:",listAND(list1,list2))
In [10]:
# versions of listOR and listAND which pad the returned list
# to the length of the longer input list
def listOR(list1,list2):
n1 = list2int(list1)
n2 = list2int(list2)
n3 = n1|n2
list3 = int2list(n3,max(len(list1),len(list2)))
return list3
def listAND(list1,list2):
n1 = list2int(list1)
n2 = list2int(list2)
n3 = n1&n2
list3 = int2list(n3,max(len(list1),len(list2)))
return list3
list1 = [0,1,1,1,1,0,0,0]
list2 = [0,0,0,0,1,1,1,0]
print("OR: ",listOR(list1,list2))
print("AND:",listAND(list1,list2))