Check if all values in the same index among several lists are false

Question:

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..."
Asked By: Matt Wilson

||

Answers:

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.

Answered By: Artie Vandelay

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)]
Answered By: ogdenkev

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
Answered By: Karol Milewczyk

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!

Answered By: Matt Wilson

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]
Answered By: BeRT2me
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.