5 Best Ways to Get Indices of True Values in a Binary List in Python

πŸ’‘ Problem Formulation: Python developers often work with binary lists, where 0s represent False and 1s represent True values. The challenge is to extract the indices of all the True (1) values within such a list. For example, given [1, 0, 1, 0, 1], the desired output would be [0, 2, 4].

Method 1: Using a for-loop with enumerate

This traditional method involves iterating over the list with a for-loop using the enumerate function to return the index and value, and collecting indices where values are true. It’s straightforward and easily understandable even by beginners.

Here’s an example:

binary_list = [1, 0, 1, 0, 1]
indices = []
for index, value in enumerate(binary_list):
    if value:
        indices.append(index)

Output: [0, 2, 4]

This snippet declares a binary list and then iterates over it using a for-loop combined with enumerate, which yields both the index and value. If a true value (1) is found, the index is added to the result list.

Method 2: Using a list comprehension

List comprehensions provide a more succinct and Pythonic alternative to for-loops, allowing the task to be completed in a single line of code. This method excels in readability and efficiency for shorter lists.

Here’s an example:

binary_list = [1, 0, 1, 0, 1]
indices = [i for i, val in enumerate(binary_list) if val]

Output: [0, 2, 4]

The example features the use of a list comprehension to iterate over the enumerated binary list, selecting indices (i) where the corresponding value (val) is true (non-zero).

Method 3: Using numpy.where

The numpy library provides the numpy.where function, which is highly optimized and best suited for large datasets. This is the go-to method for performance-critical applications.

Here’s an example:

import numpy as np
binary_list = np.array([1, 0, 1, 0, 1])
indices = np.where(binary_list == 1)[0]

Output: array([0, 2, 4])

By leveraging the numpy library, this code first converts the list into a numpy array, then uses np.where to find indices where entries equal 1, returning a numpy array with the results.

Method 4: Using the filter and lambda function combination

Combining filter with a lambda function allows for a functional programming approach to filtering indices. It’s a less common method but useful for scenarios that might later involve more complex filtering conditions.

Here’s an example:

binary_list = [1, 0, 1, 0, 1]
indices = list(filter(lambda i: binary_list[i], range(len(binary_list))))

Output: [0, 2, 4]

The code example employs a lambda function to check each index in the binary list for a true value within a filter function call, yielding a filtered object, which is then converted to a list of indices.

Bonus One-Liner Method 5: Using enumerate with a generator

Employing a generator expression with enumerate creates an iterator that yields indices of true values in the binary list, reducing memory usage for large lists.

Here’s an example:

binary_list = [1, 0, 1, 0, 1]
indices = (i for i, val in enumerate(binary_list) if val)
indices = list(indices)

Output: [0, 2, 4]

This compact example uses a generator expression in combination with enumerate for a memory-efficient resolution, and finally, converts the generator to a list.

Summary/Discussion

  • Method 1: Using a for-loop with enumerate. Straightforward and ideal for beginners. Not as succinct as other methods.
  • Method 2: Using a list comprehension. More Pythonic and readable for small to medium lists. Efficiency might decrease with larger datasets.
  • Method 3: Using numpy.where. Highly efficient for large arrays. Requires numpy and additional memory for converting lists to numpy arrays.
  • Method 4: Using the filter and lambda function combination. Good for expandable filtering conditions. May have less performance and readability compared to list comprehensions.
  • Method 5: Using enumerate with a generator. Memory-efficient for very large lists. Less immediate in terms of understanding compared to a list comprehension.