Reputation: 1285
I have a list of lists of boolean values. I'm trying to return a list of indexes where all values in the same positions are only False. So in the example below, position 3
and 4
of each inner list are False, so return [3,4]
.
Some assumptions to keep in mind, the list of lists could contain X number of lists, so can't rely on just three, it could be 50. Also, the inner lists will always have equal lengths, so no worrying about different-sized lists, but they could be longer than 6 like in the example I gave. So the solution must work for dynamic sizes/lengths.
list1 = [True, True, True, False, False, False]
list2 = [True, True, False, False, False, False]
list3 = [True, True, True, False, False, True]
list_of_lists = [list1, list2, list3]
result_list_of_all_false_indexes = []
# Pseudo code
# Look in position 0 of each list in the list of lists. If they're all false
# result_list_of_all_false_indexes.append(index)
# Look in position 1 of each list in the list of lists. If they're all false
# result_list_of_all_false_indexes.append(index)
# continue for entire length of inner lists
assert result_list_of_all_false_indexes == [3,4], "Try again..."
Upvotes: 1
Views: 398
Reputation: 2374
I would use zip to unpack the list_of_lists
and enumerate to get the indexes. Then the any function can be used with not
to test for all False
values.
import random
n_lists = random.randrange(1, 20)
n_elements = random.randrange(3, 10)
# I set the relative weights to favor getting all False entries
list_of_lists = [
random.choices([True, False], k=n_elements, weights=[1, 10])
for i in range(n_lists)
]
result_list_of_all_false_indexes = [i for i, vals in enumerate(zip(*lol)) if not any(vals)]
Upvotes: 2
Reputation: 13242
With some help from numpy, we can check your conditions by axis:
import numpy as np
results = np.where(~np.any(list_of_lists, axis=0))[0].tolist()
# Output:
[3, 4]
Upvotes: 2
Reputation: 1285
Thanks to @Cleb in the comments, I was able to make this work:
from numpy import where, any
list1 = [True, True, True, False, False, False]
list2 = [True, True, False, False, False, False]
list3 = [True, True, True, False, False, True]
list_of_lists = [list1, list2, list3]
result = where(np.any(list_of_lists, axis=0) == False)[0]
print(result)
assert result == [3,4], "Try again..."
Rather than using all
(which evaluates to ALL values on a certain access are True
) I used any
and ==False
to accomplish what I was after.
It fails the assertion as it's now in an array format (not list separated by commas), but that's fine with me. A little more concise than having to use iteration, but either will work. Thanks all!
Upvotes: 0
Reputation: 350
lol - list of lists
output - returns desired list of indexes.
def output(lol):
res = []
if lol: # Checks if list contains any list at all
res = [i for i in range(len(lol[0]))]
for list_ in lol:
res = [i for i in res if not list_[i]]
if not res:
break
return res
Upvotes: 2
Reputation: 476
result_list_of_all_false_indexes = []
for i in range(len(list_of_lists[0])):
if not any(lst[i] for lst in list_of_lists):
result_list_of_all_false_indexes.append(i)
EDIT: added explanation
Iterate over each possible index, and then check if each list at that index is False. If so, add the index to your results list.
Upvotes: 1