How to mask a list using boolean values from another list
Question:
I have a list like this:
x = [True, False, True, False]
and a list like this:
y = [a, b, c, d]
I would like to mask x
over y
to get this output:
output = [a, c]
I know how to do this using while
/for
loops, but I’m ideally looking for an elegant one-line of code using list comprehension.
Answers:
You can use zip
and a list comprehension to perform a filter operation on y
based on corresponding truth values in x
:
x = [True, False, True, False]
y = ["a", "b", "c", "d"]
print([b for a, b in zip(x, y) if a])
Output:
['a', 'c']
itertools.compress
also does this:
>>> from itertools import compress
>>> x = [True, False, True, False]
>>> y = ["a", "b", "c", "d"]
>>> list(compress(y, x))
['a', 'c']
I think the easiest way is to use numpy
:
import numpy as np
>>> x = [True, False, True, False]
>>> y = ['a', 'b', 'c', 'd']
>>> np.array(y)[x]
array(['a', 'c'], dtype='<U1')
Without numpy
, You could also enumerate in a list comprehension:
>>> [i for idx, i in enumerate(y) if x[idx]]
['a', 'c']
This is rather simple to solve. Consider writing properly your list:
x = [True, False, True, False]
y = [a, b, c, d] # assuming that a, b, c and d are some kind of object
output = []
for i, k in enumerate(x):
if k:
output.append(x[i])
There are several ways to do this.
The simplest way would be to zip the two lists together and use a list comprehension to keep the items you want.
x = [True, False, True, False]
y = ['a', 'b', 'c', 'd']
print([item for keep, item in zip(x, y) if keep])
You can also convert the y array to a numpy array and use the x array to mask the numpy array.
import numpy as np
x = [True, False, True, False]
y = ['a', 'b', 'c', 'd']
print(list(np.array(y)[x]))
Finally, you can create an empty list, iterate through the x and y arrays using their indexes, and append elements in y to the empty list if the corresponding element in x is True.
x = [True, False, True, False]
y = ['a', 'b', 'c', 'd']
temp = []
for index in range(len(y)):
if x[index]:
temp.append(y[index])
print(temp)
If already have you some function that returns True/False for each element y, use filter(), example:
list(filter(lambda x: x < 'c' , y))
Or
my_iter = iter([True, False, True, False])
list(filter(lambda x: next(my_iter), y))
I have a list like this:
x = [True, False, True, False]
and a list like this:
y = [a, b, c, d]
I would like to mask x
over y
to get this output:
output = [a, c]
I know how to do this using while
/for
loops, but I’m ideally looking for an elegant one-line of code using list comprehension.
You can use zip
and a list comprehension to perform a filter operation on y
based on corresponding truth values in x
:
x = [True, False, True, False]
y = ["a", "b", "c", "d"]
print([b for a, b in zip(x, y) if a])
Output:
['a', 'c']
itertools.compress
also does this:
>>> from itertools import compress
>>> x = [True, False, True, False]
>>> y = ["a", "b", "c", "d"]
>>> list(compress(y, x))
['a', 'c']
I think the easiest way is to use numpy
:
import numpy as np
>>> x = [True, False, True, False]
>>> y = ['a', 'b', 'c', 'd']
>>> np.array(y)[x]
array(['a', 'c'], dtype='<U1')
Without numpy
, You could also enumerate in a list comprehension:
>>> [i for idx, i in enumerate(y) if x[idx]]
['a', 'c']
This is rather simple to solve. Consider writing properly your list:
x = [True, False, True, False]
y = [a, b, c, d] # assuming that a, b, c and d are some kind of object
output = []
for i, k in enumerate(x):
if k:
output.append(x[i])
There are several ways to do this.
The simplest way would be to zip the two lists together and use a list comprehension to keep the items you want.
x = [True, False, True, False]
y = ['a', 'b', 'c', 'd']
print([item for keep, item in zip(x, y) if keep])
You can also convert the y array to a numpy array and use the x array to mask the numpy array.
import numpy as np
x = [True, False, True, False]
y = ['a', 'b', 'c', 'd']
print(list(np.array(y)[x]))
Finally, you can create an empty list, iterate through the x and y arrays using their indexes, and append elements in y to the empty list if the corresponding element in x is True.
x = [True, False, True, False]
y = ['a', 'b', 'c', 'd']
temp = []
for index in range(len(y)):
if x[index]:
temp.append(y[index])
print(temp)
If already have you some function that returns True/False for each element y, use filter(), example:
list(filter(lambda x: x < 'c' , y))
Or
my_iter = iter([True, False, True, False])
list(filter(lambda x: next(my_iter), y))