Sắp Xếp List Python: 2 Cách Tăng & Giảm Dần Tối Ưu Nhất
Sắp Xếp List Python: 2 Cách Tăng & Giảm Dần Tối Ưu Nhất

Bài viết này sẽ hướng dẫn bạn chi tiết các phương pháp cơ bản và tối ưu nhất để giải quyết bài toán sắp xếp danh sách trong Python. Chúng ta sẽ cùng đi sâu vào bản chất vùng nhớ, phân tích độ phức tạp và cách Python xử lý dữ liệu ngầm định bên dưới.

💡 Trả lời nhanh: Để sắp xếp list trong Python, bạn có hai lựa chọn chính là dùng phương thức list.sort() hoặc hàm built-in sorted(). Phương thức list.sort() sẽ thay đổi trực tiếp danh sách hiện tại (in-place) và không trả về danh sách mới. Ngược lại, hàm sorted(list) sẽ giữ nguyên danh sách gốc và tạo ra một bản sao hoàn toàn mới đã được sắp xếp. Cả hai đều hỗ trợ tham số reverse=True để đảo ngược trật tự thành sắp xếp giảm dần.


Đề bài 

Viết chương trình Python nhận vào một danh sách (list) chứa các phần tử (ví dụ: các số nguyên hoặc số thực). Yêu cầu sắp xếp danh sách này theo hai chiều: tăng dần (từ nhỏ đến lớn) và giảm dần (từ lớn đến nhỏ).

Input: Một list chứa các số nguyên/thực, ví dụ: [5, 2, 9, 1, 5, 6].

Output: Danh sách đã được sắp xếp tăng dần [1, 2, 5, 5, 6, 9] và danh sách đã được sắp xếp giảm dần [9, 6, 5, 5, 2, 1].

Ràng buộc: Các phần tử trong danh sách phải đồng nhất về khả năng so sánh (không chứa lẫn lộn chuỗi và số). Cần xử lý các ngoại lệ nếu dữ liệu đầu vào không hợp lệ.


Phân tích 

Bài toán sắp xếp list trong Python yêu cầu chúng ta tổ chức lại các phần tử theo một trật tự tuyến tính nhất định bằng các công cụ có sẵn của ngôn ngữ. Đối với sinh viên năm 2 hoặc những người đã nắm cơ bản về lập trình, việc sắp xếp không chỉ đơn thuần là gọi hàm cho ra kết quả, mà còn là bài toán về quản lý bộ nhớ và hiệu năng. Python sử dụng thuật toán Timsort (kết hợp giữa Merge Sort và Insertion Sort) làm thuật toán cốt lõi bên dưới cho mọi thao tác sắp xếp.

Khi xử lý danh sách, chúng ta luôn phải đối mặt với tính chất “Mutable” (có thể thay đổi) của kiểu dữ liệu List. Việc sắp xếp có thể thao tác trực tiếp trên chính vùng nhớ của List đó, hoặc cấp phát một vùng nhớ mới để lưu trữ kết quả. Điều này dẫn đến hai trường phái giải quyết bài toán: sắp xếp tại chỗ (in-place) và sắp xếp tạo bản sao (out-of-place).

📌 Góc nhìn thực tế: Trong thực tế, sinh viên và kể cả lập trình viên đi làm rất hay nhầm lẫn giữa việc thay đổi dữ liệu gốc và tạo dữ liệu mới. Hậu quả là vô tình làm mất đi thứ tự ban đầu của dữ liệu log hệ thống, dẫn đến việc không thể truy vết lại luồng sự kiện theo thời gian thực.

Giả định

Chúng ta giả định rằng người dùng có thể muốn giữ lại danh sách ban đầu để phục vụ cho các phép toán khác sau này, hoặc họ chỉ muốn sắp xếp trực tiếp để tiết kiệm bộ nhớ RAM. Do đó, bài viết sẽ trình bày cả hai hướng tiếp cận độc lập để bạn có thể linh hoạt áp dụng vào từng ngữ cảnh cụ thể của dự án.

Chính vì sự khác biệt trong cách quản lý vùng nhớ này, chúng ta sẽ lần lượt đi vào hai cách giải quyết: dùng phương thức tích hợp sẵn của object List và dùng hàm độc lập của Python.


Cách giải 1: Phương thức list.sort() 

Cách sắp xếp list tăng giảm bằng list.sort() là phương pháp can thiệp trực tiếp vào bản thân đối tượng danh sách đang tồn tại trong bộ nhớ.

Ý tưởng

Khởi nguồn của cách làm này là triết lý tối ưu hóa tài nguyên. Thay vì phải xin hệ điều hành cấp phát thêm một khoảng RAM mới bằng với kích thước của danh sách cũ, phương thức này sẽ xáo trộn và đổi chỗ các phần tử ngay bên trong không gian hiện tại của nó. Kết quả là danh sách gốc bị thay đổi hình hài hoàn toàn. Thuật toán sẽ duyệt qua các phần tử, so sánh chúng và đẩy các giá trị nhỏ về đầu mảng (hoặc ngược lại nếu bạn yêu cầu giảm dần).

Các bước

  1. Xác định danh sách cần sắp xếp (đảm bảo nó là kiểu list).

  2. Gọi trực tiếp phương thức .sort() từ biến chứa danh sách đó thông qua dấu chấm.

  3. Để sắp xếp tăng dần, để trống tham số: my_list.sort().

  4. Để sắp xếp list giảm, truyền thêm tham số từ khóa reverse=True vào trong ngoặc: my_list.sort(reverse=True).

  5. Phương thức sẽ trả về None, bạn chỉ cần in lại biến my_list để xem kết quả.

Minh họa tay

Giả sử ta có lst = [3, 1, 4, 1, 5, 9]

  • Trạng thái ban đầu trong RAM: lst trỏ tới vùng nhớ [3, 1, 4, 1, 5, 9]

  • Gọi lst.sort():

    • Timsort bắt đầu chia nhỏ mảng và gộp lại.

    • Vùng nhớ biến đổi dần: [1, 1, 3, 4, 5, 9].

  • Kết thúc: lst vẫn trỏ tới vùng nhớ cũ, nhưng nội dung bên trong đã là [1, 1, 3, 4, 5, 9].

  • Gọi tiếp lst.sort(reverse=True):

    • Vùng nhớ đảo trật tự trực tiếp: [9, 5, 4, 3, 1, 1].

Đánh giá

  • Phù hợp người mới vì: Cú pháp vô cùng ngắn gọn, dễ nhớ, mang tính hướng đối tượng rõ ràng.

  • Ưu điểm: Tiết kiệm bộ nhớ tuyệt đối (độ phức tạp không gian bổ sung là rất thấp). Thích hợp cho các danh sách chứa hàng triệu phần tử (Big Data) khi RAM là một rào cản lớn.

  • Nhược điểm: Dữ liệu gốc bị ghi đè vĩnh viễn. Nếu bạn cần so sánh mảng trước và sau khi sắp xếp, cách này sẽ làm bạn mất dữ liệu cũ.

  • Độ phức tạp: O(N log N) thời gian / O(N) bộ nhớ trong trường hợp xấu nhất của Timsort, nhưng không tốn kém thêm chi phí tạo list object mới.

Mặc dù rất hiệu quả về mặt bộ nhớ, nhưng đôi khi sự an toàn của dữ liệu gốc lại quan trọng hơn. Đó là lý do chúng ta có Cách 2.


Cách giải 2: Hàm built-in sorted() 

Khác với Cách 1, cách tạo list mới đã sắp xếp bằng hàm sorted() hoạt động theo nguyên tắc “bất biến” (immutable-like behavior) đối với đầu vào, bảo vệ tuyệt đối dữ liệu gốc của bạn.

Ý tưởng

Ý tưởng cốt lõi của hàm sorted() là nó đóng vai trò như một nhà máy sản xuất. Nó tiếp nhận nguyên liệu thô (là danh sách gốc của bạn), đọc và sao chép các giá trị, sau đó áp dụng thuật toán sắp xếp Timsort trên bản sao này. Cuối cùng, nó trả về cho bạn một thành phẩm hoàn toàn mới (một danh sách thứ hai độc lập trong bộ nhớ). Danh sách gốc ban đầu không hề bị tác động hay xê dịch bất kỳ phần tử nào.

Các bước

  1. Định nghĩa danh sách ban đầu của bạn.

  2. Khai báo một biến mới để hứng kết quả trả về, ví dụ: new_list = ....

  3. Gọi hàm sorted() và truyền danh sách gốc vào làm đối số: new_list = sorted(old_list).

  4. Tương tự như cách 1, nếu muốn sắp xếp theo chiều giảm dần, bạn thêm đối số reverse=True: new_list = sorted(old_list, reverse=True).

  5. Lúc này, bạn có thể sử dụng song song cả new_list (đã sắp xếp) và old_list (chưa sắp xếp).

Minh họa tay

Giả sử ta có old_lst = [3, 1, 4, 1, 5, 9]

  • Trạng thái RAM: old_lst trỏ tới vùng nhớ A [3, 1, 4, 1, 5, 9].

  • Gọi new_lst = sorted(old_lst):

    • Python cấp phát vùng nhớ B hoàn toàn mới.

    • Thuật toán đọc vùng nhớ A, tính toán và ghi trật tự mới vào vùng nhớ B.

  • Kết thúc:

    • old_lst (Vùng nhớ A) vẫn là [3, 1, 4, 1, 5, 9].

    • new_lst (Vùng nhớ B) chứa [1, 1, 3, 4, 5, 9].

Khi nào nên dùng Cách 2?

Cách tiếp cận này được ưu tiên tuyệt đối trong lập trình hàm (Functional Programming) hoặc khi bạn đang xử lý luồng dữ liệu mà trạng thái ban đầu của dữ liệu là quan trọng. Ví dụ: bạn cần hiển thị danh sách điểm số theo thứ tự nhập vào ban đầu của lớp, đồng thời in ra một bảng vàng vinh danh những người điểm cao nhất từ trên xuống dưới. Nếu dùng cách 1, bạn sẽ phá hỏng danh sách lớp ban đầu.

Đánh giá

  • Ưu điểm: An toàn dữ liệu, không gây tác dụng phụ (side effects). Cực kỳ linh hoạt vì sorted() có thể nhận vào bất kỳ iterable nào (Tuple, Set, Dictionary keys) và luôn trả về một List.

  • Nhược điểm: Tốn kém bộ nhớ gấp đôi. Nếu list gốc nặng 1GB, bạn sẽ cần thêm 1GB RAM nữa để chứa list mới.

  • Độ phức tạp: O(N log N) thời gian / O(N) bộ nhớ cho việc tạo list kết quả mới.


So sánh nhanh 2 cách 

Bảng này giúp bạn quyết định nên dùng cách nào mà không cần đọc lại toàn bài khi cần phân tích đánh đổi (trade-offs).

Tiêu chí Cách 1: list.sort() Cách 2: sorted()
Ý tưởng cốt lõi Sắp xếp trực tiếp trên bộ nhớ cũ (In-place) Tạo ra một list hoàn toàn mới (Out-of-place)
Độ phức tạp O(N log N) time O(N log N) time
Dễ đọc / dễ hiểu ★★★★★ ★★★★☆
Hiệu năng (Bộ nhớ) ★★★★★ (Tối ưu nhất) ★★★☆☆ (Tốn thêm RAM)
Phù hợp khi Cần tối ưu RAM, list kích thước cực lớn, không cần giữ thứ tự cũ Cần giữ lại data gốc, hoặc input đầu vào là Tuple/Set/Dict
Không phù hợp khi Cần so sánh trước-sau, lập trình functional Thiết bị chạy code có RAM rất hạn chế (IoT, nhúng)

Code đầy đủ 

Cách 1 — Phương thức list.sort():

# Tên biến nhất quán với phần minh họa tay

def solve_in_place(lst: list, desc: bool = False) -> list:
    """
    Sắp xếp list trực tiếp trên bộ nhớ gốc.
    Nhận vào một list và cờ desc (mặc định False = tăng dần, True = giảm dần).
    Trả về chính list đó sau khi đã bị biến đổi.
    """
    try:
        # Gọi phương thức sort() can thiệp thẳng vào lst
        lst.sort(reverse=desc)
        return lst
    except TypeError as e:
        print(f"Lỗi: Danh sách chứa các kiểu dữ liệu không thể so sánh với nhau. Chi tiết: {e}")
        return []

# --- Nhập liệu ---
# Giả định input được nhập dưới dạng các số cách nhau bởi dấu phẩy
try:
    raw_input = input("Nhập các số, cách nhau bởi dấu phẩy: ")
    # Chuyển chuỗi đầu vào thành list các số thực
    my_list = [float(x.strip()) for x in raw_input.split(',')]
    
    print(f"Danh sách gốc (trước sắp xếp): {my_list}")
    
    # Sắp xếp tăng dần
    solve_in_place(my_list)
    print(f"Danh sách tăng dần: {my_list}")
    
    # Sắp xếp giảm dần (Lưu ý: my_list lúc này đã là mảng tăng dần)
    solve_in_place(my_list, desc=True)
    print(f"Danh sách giảm dần: {my_list}")

except ValueError:
    print("Lỗi: Vui lòng chỉ nhập số hợp lệ.")

Cách 2 — Hàm built-in sorted():

# Điểm khác với Cách 1: Hàm này sẽ không chạm vào nội dung của lst truyền vào.

def solve_out_of_place(lst: list, desc: bool = False) -> list:
    """
    Tạo list mới đã sắp xếp từ danh sách gốc.
    Nhận vào list gốc và cờ desc. Trả về một đối tượng list hoàn toàn mới.
    """
    try:
        # Hàm sorted() sinh ra vùng nhớ mới
        new_lst = sorted(lst, reverse=desc)
        return new_lst
    except TypeError as e:
        print(f"Lỗi: Không thể sắp xếp dữ liệu không đồng nhất. Chi tiết: {e}")
        return []

# --- Nhập liệu ---
try:
    raw_input = input("Nhập các số, cách nhau bởi dấu phẩy: ")
    original_list = [float(x.strip()) for x in raw_input.split(',')]
    
    print(f"Danh sách gốc (an toàn): {original_list}")
    
    # Tạo list tăng dần mới
    asc_list = solve_out_of_place(original_list)
    print(f"Danh sách mới (Tăng dần): {asc_list}")
    
    # Tạo list giảm dần mới từ list gốc
    desc_list = solve_out_of_place(original_list, desc=True)
    print(f"Danh sách mới (Giảm dần): {desc_list}")
    
    # Kiểm tra lại list gốc
    print(f"Xác nhận danh sách gốc không đổi: {original_list}")

except ValueError:
    print("Lỗi: Vui lòng chỉ nhập số hợp lệ.")

Ví dụ chạy thử 

STT Input Output (Tăng dần) Giải thích
1 [5, 2, 9, 1, 5, 6] [1.0, 2.0, 5.0, 5.0, 6.0, 9.0] Hoạt động bình thường với số nguyên (đã ép kiểu float trong code).
2 [-3.14, 0, 100, -99] [-99.0, -3.14, 0.0, 100.0] Xử lý tốt số âm và số thập phân một cách chính xác.
3 [42] [42.0] Edge case: Mảng chỉ có 1 phần tử, thuật toán trả về ngay lập tức, không sinh lỗi.

Lỗi thường gặp 

Lỗi 1: Gán kết quả của phương thức sort() vào một biến mới

Lỗi kinh điển nhất mà hầu hết sinh viên mới học Python đều mắc phải là cố gắng hứng kết quả của hàm in-place.

Hiện tượng: Output in ra biến mới có giá trị None thay vì danh sách đã sắp xếp.

Nguyên nhân: Vì nguyên tắc thiết kế API của ngôn ngữ Python do Guido van Rossum đề ra: các hàm thay đổi trực tiếp (mutate) cấu trúc dữ liệu luôn phải trả về None (Null) để nhắc nhở người lập trình rằng thao tác này đang làm thay đổi đối tượng gốc. Nếu nó trả về list, bạn sẽ dễ nhầm tưởng nó tạo ra list mới.

Code sai:

my_list = [3, 1, 2]
sorted_list = my_list.sort()
print(sorted_list) 
# output sai là: None

Code đúng:

my_list = [3, 1, 2]
my_list.sort() # Chỉ gọi phương thức trên một dòng độc lập
print(my_list)
# output đúng là: [1, 2, 3]

Lỗi 2: Sắp xếp list chứa các kiểu dữ liệu xung đột nhau

Khi lấy dữ liệu từ các nguồn không xác định (như JSON từ API, file CSV), danh sách của bạn có thể chứa “rác” không đồng nhất.

Hiện tượng: Output ra lỗi crash chương trình TypeError: '<' not supported between instances of 'str' and 'int'.

Nguyên nhân: Vì thuật toán sắp xếp cần dùng toán tử nhỏ hơn < để so sánh từng cặp phần tử. Python là ngôn ngữ strongly typed (kiểu mạnh), nó cấm tuyệt đối việc so sánh độ lớn giữa một chuỗi ký tự (str) và một con số (int). Ngôn ngữ không biết “apple” lớn hơn hay nhỏ hơn số 5.

Code sai:

mixed_list = [10, "apple", 5]
mixed_list.sort()
# output sai là: TypeError Exception

Code đúng:

mixed_list = [10, "apple", 5]
# Chuyển tất cả về chuỗi để so sánh alphabet, hoặc lọc phần tử
string_list = [str(item) for item in mixed_list]
string_list.sort()
print(string_list)
# output đúng là: ['10', '5', 'apple'] (Sắp xếp theo mã ASCII chữ số đầu)

Lỗi 3: Nhầm lẫn giữa reverse=True và hàm reversed()

Khi làm bài toán yêu cầu sắp xếp list giảm dần, nhiều bạn tìm kiếm và dùng sai công cụ đảo ngược mảng.

Hiện tượng: Output ra danh sách bị đảo chiều từ dưới lên trên, nhưng giá trị bên trong hoàn toàn lộn xộn, không hề lớn đến nhỏ.

Nguyên nhân: Vì hàm reversed() chỉ làm nhiệm vụ lật ngược mảng theo chỉ số index (phần tử cuối lên đầu), nó KHÔNG hề quan tâm đến giá trị lớn nhỏ bên trong. Để thực sự sắp xếp số từ lớn xuống nhỏ, bạn phải dùng thuật toán sort với tham số báo hiệu giảm dần reverse=True.

Code sai:

my_list = [2, 9, 1]
desc_list = list(reversed(my_list))
print(desc_list)
# output sai là: [1, 9, 2] (Chỉ lật ngược vị trí)

Code đúng:

my_list = [2, 9, 1]
desc_list = sorted(my_list, reverse=True)
print(desc_list)
# output đúng là: [9, 2, 1] (Thực sự sắp xếp giảm dần)

Lỗi 4: Cố gắng dùng sort() trên một Tuple

Trong quá trình refactor code, bạn chuyển dữ liệu từ List sang Tuple để bảo mật, nhưng quên cập nhật lại logic phân loại.

Hiện tượng: Output báo lỗi AttributeError: 'tuple' object has no attribute 'sort'.

Nguyên nhân: Vì Tuple trong Python là cấu trúc dữ liệu Immutable (bất biến). Một khi đã tạo ra, nó không thể bị thay đổi độ dài hay trật tự bên trong vùng nhớ. Do đó, kiểu Tuple không hề sở hữu phương thức .sort(). Để giải quyết, bạn bắt buộc phải dùng hàm sorted() (nó sẽ nhận tuple và nhả ra một list mới).

Code sai:

my_tuple = (5, 2, 8)
my_tuple.sort()
# output sai là: AttributeError

Code đúng:

my_tuple = (5, 2, 8)
new_list = sorted(my_tuple)
print(new_list)
# output đúng là: [2, 5, 8]

Lỗi 5: Đột biến List trong khi đang dùng vòng lặp sắp xếp tự viết

Dù ít xảy ra với hàm built-in, nhưng khi sinh viên được yêu cầu tự viết thuật toán sắp xếp (như Bubble Sort), lỗi này rất phổ biến.

Hiện tượng: Output ra mảng bị thiếu phần tử, hoặc chương trình bị treo (infinite loop), IndexError out of range.

Nguyên nhân: Vì bạn đang dùng vòng lặp for item in my_list và bên trong vòng lặp đó bạn lại chèn, xóa hoặc thay đổi độ dài của chính my_list. Iterator của Python bị mất phương hướng khi cấu trúc dữ liệu nền tảng dưới chân nó đang bị dịch chuyển liên tục.

Code sai:

my_list = [3, 1, 2]
for x in my_list:
    # Logic thêm/xóa phần tử trong lúc lặp
    my_list.remove(x) 
# output sai là: Bỏ qua phần tử do index trượt đi

Code đúng:

my_list = [3, 1, 2]
# Luôn lặp qua một BẢN SAO của list nếu muốn sửa list gốc
for x in my_list[:]:
    my_list.remove(x)
# output đúng là: List rỗng như kỳ vọng

Câu hỏi thường gặp 

Sắp xếp list trong Python là gì?

Sắp xếp list trong Python là quá trình sắp đặt lại các phần tử bên trong cấu trúc dữ liệu danh sách theo một trật tự toán học hoặc logic nhất định. Ngôn ngữ cung cấp sẵn phương thức list.sort() hoặc hàm sorted() để bạn dễ dàng tổ chức lại dữ liệu thành dạng tăng dần hoặc giảm dần mà không cần tự code thuật toán thủ công.

Các thuật toán sắp xếp list tăng dần hoạt động thế nào trong Python?

Trình thông dịch Python sử dụng thuật toán có tên là Timsort bên dưới mui xe để xử lý việc sắp xếp list tăng. Đây là một thuật toán lai cực kỳ tối ưu, kết hợp giữa thuật toán Merge Sort (chia để trị) và Insertion Sort (sắp xếp chèn), giúp nó xử lý cực nhanh các đoạn dữ liệu đã được sắp xếp một phần từ trước.

Làm thế nào để sắp xếp list giảm dần bằng Python?

Để sắp xếp list giảm dần bằng Python, bạn chỉ cần gọi phương thức sắp xếp và truyền thêm tham số từ khóa reverse=True. Cụ thể, bạn viết my_list.sort(reverse=True) nếu muốn thay đổi mảng hiện tại, hoặc new_list = sorted(my_list, reverse=True) nếu muốn tạo ra một danh sách mới đảo ngược chiều từ lớn đến nhỏ.

Cách dùng hàm sorted() để sắp xếp list Python như thế nào?

Cách dùng hàm sorted() để sắp xếp list Python rất đơn giản: bạn đặt danh sách cần xử lý vào trong dấu ngoặc đơn của hàm. Khác với cách gọi hàm có dấu chấm, bạn viết sorted(tên_danh_sách) và gán nó vào một biến mới, vì hàm này sẽ tự động sinh ra một vùng nhớ mới chứa các phần tử đã nằm đúng vị trí.

Nên dùng list.sort() hay sorted() để sắp xếp danh sách?

Bạn nên dùng list.sort() khi bạn có một danh sách khổng lồ, cần tiết kiệm RAM và không quan tâm đến việc bị mất thứ tự dữ liệu cũ. Ngược lại, hãy chọn hàm sorted() khi bạn bắt buộc phải duy trì danh sách gốc để đối chiếu, hoặc khi dữ liệu đầu vào của bạn không phải là list (chẳng hạn như Tuple hay Set).

Sự khác biệt về bộ nhớ giữa 2 cách sắp xếp list này là gì?

Sự khác biệt lớn nhất về bộ nhớ giữa 2 cách sắp xếp list nằm ở khâu cấp phát RAM. Phương thức in-place .sort() có độ phức tạp không gian phụ trợ là $O(1)$ đến $O(N)$ nhưng tái sử dụng bộ nhớ cũ, cực kỳ tiết kiệm. Trong khi hàm out-of-place sorted() luôn luôn chiếm dụng thêm ít nhất $O(N)$ không gian để xây dựng cấu trúc danh sách hoàn toàn mới.

Tại sao code sắp xếp list Python trả về giá trị None?

Code sắp xếp list Python trả về giá trị None khi bạn cố gắng in hoặc gán kết quả của phương thức .sort(). Thiết kế này của Python tuân thủ nguyên tắc Command-Query Separation: một hàm làm thay đổi trạng thái đối tượng (mutate) thì không được phép trả về đối tượng đó, giúp lập trình viên không nhầm lẫn giữa việc sửa mảng gốc và tạo mảng mới.


Kết luận

Qua bài viết, bạn đã nắm vững hai triết lý cốt lõi khi xử lý bài toán thao tác trên danh sách. Hãy dùng phương thức .sort() như một công cụ sắc bén khi bạn muốn dọn dẹp trực tiếp vùng nhớ, và tận dụng hàm sorted() như một cỗ máy photocopy an toàn khi dữ liệu gốc là bất khả xâm phạm. Tùy thuộc vào yêu cầu của bài toán (tối ưu bộ nhớ hay giữ nguyên trạng thái), việc chọn đúng công cụ sẽ giúp code của bạn không chỉ chạy đúng mà còn thể hiện tư duy của một lập trình viên Python chuyên nghiệp.

Các khóa học liên quan: 

Một số sản phẩm từ Python:

Một số sách lập trình Python bạn hãy tham khảo

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *