5 Best Ways to Display an Upper Triangular Matrix in Python

πŸ’‘ Problem Formulation: An upper triangular matrix is a matrix in which all the elements below the main diagonal are zero. Given a square matrix as input, the task is to return or display only the upper triangular part of that matrix. For example, given the square matrix [[1, 2, 3], [4, 5, 6], [7, 8, 9]], the desired upper triangular matrix output is [[1, 2, 3], [0, 5, 6], [0, 0, 9]].

Method 1: Using a Nested Loop

For each row in the matrix, we loop through the columns, setting elements to zero if the column index is less than the row index. This method is direct and easy to understand.

Here’s an example:

def upper_triangular(matrix):
    nrows = len(matrix)
    for i in range(nrows):
        for j in range(i):
            matrix[i][j] = 0
    return matrix

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(upper_triangular(matrix))

Output:

[[1, 2, 3], [0, 5, 6], [0, 0, 9]]

This code defines a function upper_triangular() that takes a square matrix and sets the elements below the main diagonal to zero, transforming it into an upper triangular matrix. The nested for loops iterate through the matrix in a way that preserves the upper triangle’s values while overwriting the lower triangle.

Method 2: Using List Comprehensions

In Python, list comprehensions provide a concise way to create lists. You can use them to construct the upper triangular matrix by including elements conditionally based on their index values. This method is more Pythonic than using nested loops.

Here’s an example:

def upper_triangular(matrix):
    nrows = len(matrix)
    return [[matrix[i][j] if j >= i else 0 for j in range(nrows)] for i in range(nrows)]

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(upper_triangular(matrix))

Output:

[[1, 2, 3], [0, 5, 6], [0, 0, 9]]

The function upper_triangular() uses a nested list comprehension to build the desired upper triangular matrix. It keeps the original element if the column index is greater than or equal to the row index; otherwise, it places a zero.

Method 3: Utilizing NumPy Library

NumPy is a popular library for numerical computing in Python. It provides a function called triu() which takes a matrix and returns the upper triangular part, setting the rest of the elements to zero.

Here’s an example:

import numpy as np

matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
upper_matrix = np.triu(matrix)

print(upper_matrix)

Output:

[[1 2 3]
 [0 5 6]
 [0 0 9]]

The code converts the input matrix into a NumPy array, then uses the np.triu() function to extract the upper triangular portion. This method is efficient and the most straightforward when using NumPy.

Method 4: Using the zip() Function

The built-in zip() function can be used to iterate over the rows of a matrix in parallel, which can help in filtering out the lower triangular elements by replacing them with zero.

Here’s an example:

def upper_triangular(matrix):
    return [list((0 if j < i else ele) for j, ele in enumerate(row)) for i, row in enumerate(matrix)]

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(upper_triangular(matrix))

Output:

[[1, 2, 3], [0, 5, 6], [0, 0, 9]]

The function upper_triangular() goes through each row with its index and sets the elements to zero if their column index is less than the row index. It achieves the same result as a nested loop but does so in a more functional programming style using enumerate() and a generator expression.

Bonus One-Liner Method 5: Lambda Function with Map

A compact one-liner method uses a combination of lambda function and map() to replace lower triangular elements with zero. This approach favors brevity over clarity.

Here’s an example:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
upper_triangle = map(lambda i_row: (0 if j < i else ele for j, ele in enumerate(i_row[1])), enumerate(matrix))

print(list(map(list, upper_triangle)))

Output:

[[1, 2, 3], [0, 5, 6], [0, 0, 9]]

This one-liner constructs an upper triangular matrix by replacing elements in a functional way. The map() function applies the lambda to each row, which uses list comprehension to generate the required rows of the upper triangular matrix.

Summary/Discussion

  • Method 1: Nested Loop. Straightforward and easy for beginners to understand. However, it may be less efficient for large matrices due to the explicit loop.
  • Method 2: List Comprehensions. Cleaner and more idiomatic Python code. Might be hard to read for those not familiar with list comprehensions.
  • Method 3: Using NumPy Library. Most efficient and simplest for those already including NumPy in their projects. Not suitable without external dependencies.
  • Method 4: Using zip(). Functional programming approach, which can be less intuitive but offers an elegant solution. It may also lead to harder-to-debug code.
  • Method 5: Lambda with Map. Very concise, but potentially confusing due to its dense one-liner nature. Good for code golf but not recommended for readability.