Nhân 2 ma trận bằng Python

Em chào mọi người,

Em mới học Python và có thử làm về tạo list kết quả khi nhân 2 ma trận.
Em đã thử chạy cái này trong main và hoạt động OK không có vấn đề gì.
Tuy nhiên khi em đưa vào trong function thì lại xảy ra lỗi.
Em có thử debug để xem code hoạt động thế nào, thì lỗi nó như sau:

  • Tất cả các giá trị hàng đầu đều đúng, tuy nhiên nó cũng gán giá trị của hàng đầu cho tất cả các hàng sau. Vì thế dẫn đến KQ là em xuất ra ma trận với các hàng mang KQ y chang nhau

Không biết em bị lỗi chỗ nào các anh/ chị có thể gợi ý giúp em được không

def matrixMul(arr1, arr2):
    result = [[0]*len(arr2[0])]*len(arr1)

    for i in range(len(arr1)):
 
    # iterating by column by B
        for j in range(len(arr2[0])):
 
        # iterating by rows of B
            for k in range(len(arr2)):
                result[i][j] += arr1[i][k] * arr2[k][j]
    
    for x in result:
        print(x)
        
    return result

Bạn đăng lỗi của bạn lên đây, trong đó có thông tin lỗi ở đâu, dòng nào, lỗi gì rồi.

1 Like

Bạn nên đặt thêm tên biến cho dễ đọc và đỡ nhầm :slight_smile:

Biểu thức [0]*len(arr2[0]) không hề tạo ra đối tượng 0 nào mới cả, mà chỉ có rất nhiều tham chiếu đến duy nhất 1 đối tượng 0. Điểm khác biệt là mỗi phép tính toán số đều trả về một số, chứ không thay đổi toán hạng (ngay cả += cũng chỉ là viết tắt) nên tới đây vẫn không sai.

Tương tự, khi nhân list với số thì chỉ có 1 list mới được tạo ra bao gồm các tham chiếu đến 1 list duy nhất.

Như vậy, chỉ có 2 list được tạo ra:

  • List X gồm các tham chiếu đến 0
  • List Y gồm các tham chiếu đến X.

Vì vậy ta cần dùng đến list comprehension. List comprehension gồm 4 phần [ (1) for (2) in (3) if (4) ], với (4) là điều kiện cho (2), không phải là thành phần bắt buộc. (2) là biến lặp trên (3). (1) là biểu thức bất kỳ. Chìa khóa là, mỗi lần ta viết [] là ra một list mới :smiley: vậy (1) chính là [0]*len(arr2[0]).

3 Likes

Đây là code khi em chạy thử:

def matrixMul(arr1, arr2):
    result = [[0]*len(arr2[0])]*len(arr1)

    for i in range(len(arr1)):
 
    # iterating by column by B
        for j in range(len(arr2[0])):
 
        # iterating by rows of B
            for k in range(len(arr2)):
                result[i][j] += arr1[i][k] * arr2[k][j]
    
    for x in result:
        print(x)
        
    return result


A = [[12, 7, 3],
    [4, 5, 6],
    [7, 8, 9]]
 
# take a 3x4 matrix
B = [[5, 8, 1, 2],
    [6, 7, 3, 0],
    [4, 5, 9, 1]]


C = matrixMul(A, B)

kết quả cho ra là

[307, 414, 245, 64]
[307, 414, 245, 64]
[307, 414, 245, 64]

Cơ mà nếu nó không hề tạo ra đối tượng nào là 0 thì em có thử test in cái list đó ra trong function nó vẫn ra 1 list 0 (gồm 3 hàng 4 cột).
Cách tạo list trên là em tham khảo trên website này:
Python | Using 2D arrays/lists the right way - GeeksforGeeks
Em thấy anh có nói chìa khóa là [0]*len(arr2[0]), cơ mà em thực hiện nhân thêm như kia không đúng ạ :3

Đọc kỹ lại đoạn đó bạn nhé, mình đang hướng dẫn cách dùng list comprehension :slight_smile:

Tiếp theo, ta cần len(arr1) phần tử và biểu thức không có biến lặp nên: for _ in range(len(arr1))

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?