Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Cộng nested tuple trong Python

Khi cần thực hiện phép cộng element-wise cho nested tuple (tuple của các tuple), có thể dùng zip() lồng nhau kết hợp generator expression.

zip() gom các iterable lại theo cặp phần tử cùng vị trí.

Generator expression tạo iterator lười biếng (lazy evaluation).

Ví dụ

# Hai nested tuple cùng cấu trúc 3x2
tuple_1 = ((7, 8), (3, 4), (3, 2))
tuple_2 = ((9, 6), (8, 2), (1, 4))

print(f"Tuple 1: {tuple_1}")
print(f"Tuple 2: {tuple_2}")

# zip cấp 1: ghép hàng tương ứng -> ((7,8),(9,6)), ((3,4),(8,2)), ((3,2),(1,4))
# zip cấp 2: trong mỗi cặp hàng, ghép cột tương ứng
result = tuple(
    tuple(a + b for a, b in zip(row1, row2))
    for row1, row2 in zip(tuple_1, tuple_2)
)

print(f"\nKết quả cộng: {result}")

Kết quả

Tuple 1: ((7, 8), (3, 4), (3, 2))
Tuple 2: ((9, 6), (8, 2), (1, 4))
Kết quả cộng: ((16, 14), (11, 6), (4, 6))

Giải thích

  • zip(tuple_1, tuple_2) tạo cặp hàng: ((7,8), (9,6)), ((3,4), (8,2)), ((3,2), (1,4)).
  • Generator expression ngoài: for row1, row2 in zip(...) duyệt từng cặp hàng.
  • zip(row1, row2) tạo cặp cột: (7,9), (8,6).
  • Generator expression trong: a + b for a, b in zip(row1, row2) cộng từng cặp.
  • tuple(...) chuyển từng hàng kết quả thành tuple.
  • tuple(...) ngoài cùng chuyển toàn bộ thành nested tuple.

Cách khác: NumPy (khuyên dùng cho ma trận lớn)

import numpy as np

arr1 = np.array(tuple_1)
arr2 = np.array(tuple_2)
result_np = arr1 + arr2
print(result_np)
# [[16 14]
#  [11  6]
#  [ 4  6]]

# Chuyển về nested tuple nếu cần
result_tuple = tuple(tuple(row) for row in result_np)
print(result_tuple)

Hàm chung cho nested tuple bất kỳ

def nested_tuple_op(t1, t2, op):
    """Áp dụng phép toán op cho nested tuple cùng cấu trúc."""
    if isinstance(t1, tuple) and isinstance(t2, tuple):
        if len(t1) != len(t2):
            raise ValueError("Cấu trúc nested tuple không khớp")
        return tuple(nested_tuple_op(a, b, op) for a, b in zip(t1, t2))
    else:
        # Phần tử lá (số) -> áp dụng op
        return op(t1, t2)

import operator
print(nested_tuple_op(tuple_1, tuple_2, operator.add))
print(nested_tuple_op(tuple_1, tuple_2, operator.mul))
print(nested_tuple_op(tuple_1, tuple_2, operator.sub))

Xử lý nested tuple độ dài hàng khác nhau

from itertools import zip_longest

def nested_add_safe(t1, t2, fill=0):
    """Cộng nested tuple, điền fill cho phần tử thiếu."""
    result = []
    for row1, row2 in zip_longest(t1, t2, fillvalue=()):
        new_row = tuple(a + b for a, b in zip_longest(row1, row2, fillvalue=fill))
        result.append(new_row)
    return tuple(result)

ragged_1 = ((1, 2), (3,))
ragged_2 = ((10,), (20, 30), (40, 50))
print(nested_add_safe(ragged_1, ragged_2))
# ((11, 2), (23, 30), (40, 50))