Sắp xếp List trong Python

Python Tutorial | by Hoc Python

List là một công cụ mạnh mẽ để lưu trữ các tập hợp dữ liệu, và việc sắp xếp chúng là một thao tác cơ bản nhưng vô cùng quan trọng. Dù bạn cần sắp xếp các số, chuỗi, hay các đối tượng phức tạp hơn, Python đều cung cấp những cách đơn giản và hiệu quả để tổ chức lại dữ liệu của bạn theo một thứ tự nhất định. Hãy cùng tìm hiểu hai phương pháp chính để sắp xếp List nhé!

List là gì?

Trong Python, List (danh sách) là một trong những cấu trúc dữ liệu cơ bản và được sử dụng rộng rãi nhất. Nó được dùng để lưu trữ một tập hợp các mục (item) có thứ tự, được đặt trong cặp dấu ngoặc vuông [] và các phần tử được ngăn cách bởi dấu phẩy ,.

Các đặc điểm chính của List bao gồm:

  • Có thứ tự: Các phần tử được sắp xếp theo một trình tự cụ thể, và vị trí của chúng được xác định bằng một chỉ số (index), bắt đầu từ 0.

  • Có thể chứa nhiều kiểu dữ liệu: Một List có thể chứa các kiểu dữ liệu khác nhau cùng một lúc (số, chuỗi, boolean, thậm chí là các List khác).

  • Có thể thay đổi (Mutable): Đây là một đặc tính quan trọng, có nghĩa là bạn có thể thêm, xóa, hoặc sửa đổi các phần tử trong List sau khi nó đã được tạo ra.

Ví dụ về List:

# List chứa các số nguyên
diem_so = [8, 9, 7, 10]
print(f"List điểm số: {diem_so}")

# List chứa các chuỗi
san_pham = ["áo", "quần", "giày dép"]
print(f"List sản phẩm: {san_pham}")

Sắp xếp List là gì và tại sao cần?

Sắp xếp List là quá trình tổ chức lại các phần tử trong một List theo một thứ tự cụ thể (ví dụ: thứ tự tăng dần hoặc giảm dần đối với số, thứ tự bảng chữ cái đối với chuỗi).

Việc sắp xếp List là một thao tác rất phổ biến và cần thiết trong lập trình vì nhiều lý do:

Dễ dàng tìm kiếm và truy cập dữ liệu: Dữ liệu được sắp xếp giúp việc tìm kiếm một phần tử trở nên nhanh chóng và hiệu quả hơn rất nhiều. Tưởng tượng việc tìm một cuốn sách trong thư viện không được sắp xếp và một thư viện đã được sắp xếp theo tên tác giả!

  • Ví dụ: Tìm kiếm tên một học sinh trong danh sách đã được sắp xếp theo thứ tự bảng chữ cái sẽ nhanh hơn nhiều.

Hiển thị dữ liệu có tổ chức và dễ hiểu: Khi hiển thị dữ liệu cho người dùng, việc sắp xếp giúp thông tin trở nên rõ ràng, dễ đọc và dễ phân tích.

  • Ví dụ: Hiển thị danh sách sản phẩm theo giá từ thấp đến cao, hoặc danh sách người dùng theo tên từ A-Z.

Hỗ trợ các thuật toán khác: Nhiều thuật toán xử lý dữ liệu khác (như thuật toán hợp nhất, tìm kiếm nhị phân) yêu cầu dữ liệu đầu vào phải được sắp xếp.

Phân tích và báo cáo: Dữ liệu sắp xếp giúp việc phân tích xu hướng, xác định giá trị lớn nhất/nhỏ nhất, hoặc tạo các báo cáo thống kê trở nên đơn giản hơn.

  • Ví dụ: Sắp xếp điểm số học sinh để tìm ra top 5 học sinh có điểm cao nhất.

Hai cách tiếp cận chính để sắp xếp List

Trong Python, bạn có hai cách chính để sắp xếp một List, tùy thuộc vào việc bạn có muốn thay đổi List gốc hay không:

Sắp xếp tại chỗ (In-place sorting): Sử dụng phương thức sort() của List.

  • Cách này sẽ thay đổi trực tiếp List gốc, sắp xếp các phần tử ngay tại vị trí của chúng.

  • List sau khi sắp xếp sẽ là phiên bản đã thay đổi của List ban đầu.

Tạo List mới đã sắp xếp: Sử dụng hàm sorted().

  • Cách này sẽ tạo ra một List mới chứa các phần tử đã được sắp xếp, trong khi giữ nguyên List gốc không thay đổi.

  • Bạn cần gán kết quả của hàm sorted() vào một biến mới để sử dụng List đã sắp xếp.

Sắp xếp List tại chỗ trong Python

Khi bạn muốn sắp xếp một List và không cần giữ lại thứ tự ban đầu của nó, việc sắp xếp tại chỗ (in-place) là phương pháp hiệu quả. Điều này có nghĩa là List gốc sẽ được sửa đổi trực tiếp.

Sử dụng phương thức sort()

  • Khái niệm: Phương thức sort() là một phương thức tích hợp sẵn của đối tượng List trong Python. Nó sắp xếp các phần tử của List trực tiếp trong List đó, tức là nó thay đổi thứ tự các phần tử của List gốc mà không tạo ra một List mới.

Cú pháp:

ten_list.sort()

ten_list: Là tên của List mà bạn muốn sắp xếp.

Mặc định: Sắp xếp tăng dần Theo mặc định, sort() sẽ sắp xếp các phần tử theo thứ tự tăng dần (ascending order):

  • Đối với số: Từ nhỏ đến lớn.

  • Đối với chuỗi: Theo thứ tự từ điển (alphabetical order).

  • List chỉ có thể được sắp xếp nếu tất cả các phần tử có thể so sánh được với nhau (ví dụ: không thể sắp xếp List chứa cả số và chuỗi cùng lúc mà không có hàm key tùy chỉnh).

Ví dụ minh họa:

  • Sắp xếp số:

# List các số nguyên
numbers = [3, 1, 4, 1, 5, 9, 2]
print(f"List số ban đầu: {numbers}") # Output: List số ban đầu: [3, 1, 4, 1, 5, 9, 2]

numbers.sort() # Sắp xếp tăng dần tại chỗ
print(f"List số sau khi sort() tăng dần: {numbers}")
# Output: List số sau khi sort() tăng dần: [1, 1, 2, 3, 4, 5, 9]

Sắp xếp chuỗi:

# List các chuỗi
fruits = ["orange", "apple", "banana", "cherry"]
print(f"List chuỗi ban đầu: {fruits}") # Output: List chuỗi ban đầu: ['orange', 'apple', 'banana', 'cherry']

fruits.sort() # Sắp xếp theo thứ tự bảng chữ cái (tăng dần)
print(f"List chuỗi sau khi sort() tăng dần: {fruits}")
# Output: List chuỗi sau khi sort() tăng dần: ['apple', 'banana', 'cherry', 'orange']

Tham số reverse=True:

  • Mục đích: Để sắp xếp List theo thứ tự giảm dần (descending order), bạn có thể truyền tham số reverse=True vào phương thức sort().

Cú pháp:

ten_list.sort(reverse=True)

Ví dụ minh họa:

# List các số nguyên
numbers = [3, 1, 4, 1, 5, 9, 2]
print(f"List số ban đầu: {numbers}")

numbers.sort(reverse=True) # Sắp xếp giảm dần tại chỗ
print(f"List số sau khi sort(reverse=True): {numbers}")
# Output: List số sau khi sort(reverse=True): [9, 5, 4, 3, 2, 1, 1]

# List các chuỗi
fruits = ["orange", "apple", "banana", "cherry"]
print(f"List chuỗi ban đầu: {fruits}")

fruits.sort(reverse=True) # Sắp xếp ngược bảng chữ cái (giảm dần)
print(f"List chuỗi sau khi sort(reverse=True): {fruits}")
# Output: List chuỗi sau khi sort(reverse=True): ['orange', 'cherry', 'banana', 'apple']

Lưu ý quan trọng:

  • sort() thay đổi List gốc: Đây là điểm cốt lõi. Sau khi gọi sort(), List ban đầu của bạn sẽ không còn giữ thứ tự cũ nữa.

  • sort() không trả về giá trị gì (trả về None): Điều này có nghĩa là bạn không nên gán kết quả của sort() vào một biến mới nếu bạn muốn List đã sắp xếp. Nếu bạn cố gắng gán, biến đó sẽ nhận giá trị None.

my_list = [5, 2, 8]
result = my_list.sort() # Lỗi phổ biến: result sẽ là None!
print(f"My list sau khi sort(): {my_list}") # Output: My list sau khi sort(): [2, 5, 8]
print(f"Giá trị của result: {result}") # Output: Giá trị của result: None

Tạo List mới đã sắp xếp (Không thay đổi List gốc) trong Python

Trong nhiều trường hợp, bạn muốn sắp xếp một List nhưng đồng thời cũng muốn giữ nguyên thứ tự ban đầu của List gốc. Khi đó, bạn sẽ sử dụng hàm sorted().

Sử dụng hàm sorted()

  • Khái niệm: Hàm sorted() là một hàm tích hợp sẵn (built-in function) của Python. Khác với phương thức sort(), sorted() không thay đổi iterable gốc mà thay vào đó, nó trả về một List mới chứa tất cả các phần tử đã được sắp xếp từ iterable đầu vào.

Cú pháp:

new_list = sorted(iterable)
  • new_list: Là tên của List mới sẽ được tạo ra, chứa các phần tử đã sắp xếp.
  • iterable: Là đối tượng có thể lặp (ví dụ: List, Tuple, Set, chuỗi) mà bạn muốn sắp xếp. Hàm sorted() có thể sắp xếp bất kỳ iterable nào, không chỉ riêng List.

Mặc định: Sắp xếp tăng dần Giống như sort(), theo mặc định, sorted() sẽ sắp xếp các phần tử theo thứ tự tăng dần (ascending order):

  • Đối với số: Từ nhỏ đến lớn.

  • Đối với chuỗi: Theo thứ tự từ điển (alphabetical order).

Ví dụ minh họa:

Sắp xếp số:

# List các số nguyên gốc
original_numbers = [3, 1, 4, 1, 5, 9, 2]
print(f"List số gốc: {original_numbers}") # Output: List số gốc: [3, 1, 4, 1, 5, 9, 2]

# Tạo một List mới đã sắp xếp tăng dần
sorted_numbers = sorted(original_numbers)
print(f"List số đã sắp xếp tăng dần (mới): {sorted_numbers}")
# Output: List số đã sắp xếp tăng dần (mới): [1, 1, 2, 3, 4, 5, 9]
print(f"List số gốc (không đổi): {original_numbers}")
# Output: List số gốc (không đổi): [3, 1, 4, 1, 5, 9, 2]

Sắp xếp chuỗi:

# Tuple các chuỗi gốc
original_fruits_tuple = ("orange", "apple", "banana", "cherry")
print(f"Tuple chuỗi gốc: {original_fruits_tuple}") # Output: Tuple chuỗi gốc: ('orange', 'apple', 'banana', 'cherry')

# Tạo một List mới đã sắp xếp từ Tuple
sorted_fruits = sorted(original_fruits_tuple)
print(f"List chuỗi đã sắp xếp tăng dần (mới): {sorted_fruits}")
# Output: List chuỗi đã sắp xếp tăng dần (mới): ['apple', 'banana', 'cherry', 'orange']
print(f"Tuple chuỗi gốc (không đổi): {original_fruits_tuple}")
# Output: Tuple chuỗi gốc (không đổi): ('orange', 'apple', 'banana', 'cherry')

Tham số reverse=True:

  • Mục đích: Để sắp xếp List theo thứ tự giảm dần (descending order), bạn có thể truyền tham số reverse=True vào hàm sorted().

Cú pháp:

new_list = sorted(iterable, reverse=True)

Ví dụ minh họa:

# List các điểm số gốc
scores = [85, 92, 78, 95, 88]
print(f"List điểm số gốc: {scores}")

# Tạo một List mới đã sắp xếp giảm dần
sorted_scores_desc = sorted(scores, reverse=True)
print(f"List điểm số đã sắp xếp giảm dần (mới): {sorted_scores_desc}")
# Output: List điểm số đã sắp xếp giảm dần (mới): [95, 92, 88, 85, 78]
print(f"List điểm số gốc (không đổi): {scores}")
# Output: List điểm số gốc (không đổi): [85, 92, 78, 95, 88]

Lưu ý quan trọng:

  • Luôn gán kết quả của sorted() vào một biến mới:sorted() trả về một List mới, bạn phải gán kết quả này vào một biến để sử dụng nó. Nếu bạn không gán, List đã sắp xếp sẽ bị mất.

sorted(

my_set = {5, 2, 8, 1}
sorted_list_from_set = sorted(my_set)
print(f"Set gốc: {my_set}") # Output: Set gốc: {8, 1, 2, 5} (Thứ tự không đảm bảo cho Set)
print(f"List đã sắp xếp từ Set: {sorted_list_from_set}") # Output: List đã sắp xếp từ Set: [1, 2, 5, 8]

Các trường hợp sắp xếp nâng cao trong Python

Ngoài việc sắp xếp các số hoặc chuỗi đơn giản theo thứ tự mặc định, Python cung cấp một cách mạnh mẽ để tùy chỉnh quá trình sắp xếp thông qua tham số key.

Sử dụng tham số key (Hàm sắp xếp tùy chỉnh)

Khái niệm: Tham số key trong cả sort()sorted() cho phép bạn chỉ định một hàm (function). Hàm này sẽ được gọi một lần cho mỗi phần tử trong List (hoặc iterable) trước khi so sánh. Giá trị mà hàm key trả về cho mỗi phần tử chính là "khóa" mà quá trình sắp xếp sẽ dựa vào để quyết định thứ tự.

Tưởng tượng bạn có một List các thẻ bài. Bình thường bạn sắp xếp chúng theo tên ghi trên thẻ. Nhưng nếu bạn dùng key, bạn có thể nói: "Hãy sắp xếp các thẻ này, nhưng thay vì dùng tên, hãy dùng số điểm sức mạnh của thẻ để sắp xếp!"

Khi nào dùng?

  • Sắp xếp List chuỗi theo độ dài: Đây là một ví dụ rất phổ biến.

  • Sắp xếp List các đối tượng hoặc dictionary phức tạp: Khi bạn có một List mà mỗi phần tử là một đối tượng (ví dụ: danh sách học sinh, mỗi học sinh là một đối tượng có tên, tuổi, điểm số) hoặc một dictionary, bạn có thể muốn sắp xếp List đó dựa trên một thuộc tính cụ thể của đối tượng/dictionary (ví dụ: sắp xếp học sinh theo điểm số, hoặc sản phẩm theo giá).

  • Sắp xếp bỏ qua chữ hoa/thường: Ví dụ, sắp xếp các chuỗi mà không phân biệt chữ hoa, chữ thường.

Cú pháp cơ bản: Tham số key được truyền vào sort() hoặc sorted() như một đối số có từ khóa (keyword argument). Giá trị của key phải là một hàm (hoặc một lambda function – hàm ẩn danh).

ten_list.sort(key=my_function)
# hoặc
new_list = sorted(iterable, key=my_function)

Ví dụ minh họa ngắn: Sắp xếp List chuỗi theo độ dài. Chúng ta có một List các từ và muốn sắp xếp chúng theo độ dài từ ngắn nhất đến dài nhất.

# List các từ
words = ["apple", "banana", "cat", "dog", "elephant", "frog"]
print(f"List từ ban đầu: {words}")
# Output: List từ ban đầu: ['apple', 'banana', 'cat', 'dog', 'elephant', 'frog']

# Sắp xếp các từ theo độ dài của chúng (tăng dần)
# Hàm len() sẽ được gọi cho MỖI từ, và giá trị trả về (độ dài) sẽ được dùng để so sánh.
words.sort(key=len) # len là một hàm tích hợp sẵn trả về độ dài
print(f"List từ sau khi sort theo độ dài: {words}")
# Output: List từ sau khi sort theo độ dài: ['cat', 'dog', 'frog', 'apple', 'banana', 'elephant']

# Sử dụng sorted() để tạo một list mới sắp xếp theo độ dài (giảm dần)
fruits = ["kiwi", "grape", "blueberry", "apple"]
sorted_fruits_by_length_desc = sorted(fruits, key=len, reverse=True)
print(f"List trái cây sắp xếp theo độ dài giảm dần: {sorted_fruits_by_length_desc}")
# Output: List trái cây sắp xếp theo độ dài giảm dần: ['blueberry', 'apple', 'grape', 'kiwi']

Việc sử dụng tham số key mở ra khả năng sắp xếp rất linh hoạt, cho phép bạn định nghĩa các tiêu chí sắp xếp phức tạp mà không cần phải thay đổi cấu trúc dữ liệu ban đầu. Đây là một trong những tính năng mạnh mẽ của Python khi làm việc với các List.

Kết bài

Vậy mình đã tìm hiểu các phương pháp sắp xếp List trong Python! Dù là sắp xếp tại chỗ hay tạo List mới, Python đều mang đến những công cụ mạnh mẽ và linh hoạt giúp bạn tổ chức dữ liệu một cách hiệu quả.

Bạn giờ đây đã có trong tay:

  • my_list.sort(): Phương thức "thần tốc" để sắp xếp trực tiếp List gốc, biến đổi nó ngay tại chỗ. Hãy nhớ, nó không trả về gì cả!

  • sorted(my_list): Hàm "thân thiện" hơn, giúp bạn có được một List mới tinh đã được sắp xếp, trong khi List gốc của bạn vẫn an toàn, nguyên vẹn.

Cả hai "người hùng" này đều có thể sắp xếp tăng dần mặc định, và bạn chỉ cần thêm reverse=True để đảo ngược thứ tự thành giảm dần. Đặc biệt, "siêu năng lực" của tham số key sẽ giúp bạn tùy chỉnh việc sắp xếp theo bất kỳ tiêu chí nào bạn muốn, từ độ dài chuỗi đến thuộc tính phức tạp của đối tượng.

Khi nào dùng gì? Hãy chọn sort() khi bạn muốn một giải pháp nhanh gọn và không cần bản gốc, hoặc sorted() khi sự an toàn của dữ liệu gốc là ưu tiên hàng đầu.

Bài viết liên quan