Bài 5: Lists - Danh Sách (Phần 1)

Mục Tiêu Bài Học

Sau khi hoàn thành bài này, bạn sẽ:

  • ✅ Hiểu list là gì và khi nào dùng list
  • ✅ Tạo và truy cập phần tử trong list
  • ✅ Sử dụng indexing và slicing với list
  • ✅ Thêm, xóa, sửa phần tử trong list
  • ✅ Sử dụng list methods cơ bản

List Là Gì?

List là một collection có thứ tự, có thể thay đổi (mutable), và cho phép các phần tử trùng lặp.

# List với các kiểu dữ liệu khác nhaunumbers = [1, 2, 3, 4, 5]names = ["Alice", "Bob", "Charlie"]mixed = [1, "Hello", 3.14, True, [1, 2, 3]]empty = [] print(type(numbers))  # <class 'list'>

So sánh List vs String:

# String - immutable (không đổi)text = "Hello"# text[0] = "h"  # TypeError! Không thể thay đổi # List - mutable (có thể đổi)items = ["H", "e", "l", "l", "o"]items[0] = "h"  # ✅ OKprint(items)  # ['h', 'e', 'l', 'l', 'o']

Tạo List

Cách 1: List Literals

# Empty listempty_list = [] # List với phần tửfruits = ["apple", "banana", "orange"]numbers = [1, 2, 3, 4, 5] # Multi-line listshopping = [    "milk",    "eggs",    "bread",    "butter"] # Mixed typesmixed = [1, "two", 3.0, True, None]

Cách 2: list() Constructor

# Từ stringchars = list("Python")print(chars)  # ['P', 'y', 't', 'h', 'o', 'n'] # Từ tupletuple_data = (1, 2, 3)list_data = list(tuple_data)print(list_data)  # [1, 2, 3] # Từ rangenumbers = list(range(5))print(numbers)  # [0, 1, 2, 3, 4] numbers2 = list(range(1, 10, 2))print(numbers2)  # [1, 3, 5, 7, 9]

Cách 3: List Comprehension (nhanh)

# Tạo list từ rangesquares = [x**2 for x in range(5)]print(squares)  # [0, 1, 4, 9, 16] # Với điều kiệnevens = [x for x in range(10) if x % 2 == 0]print(evens)  # [0, 2, 4, 6, 8] # Sẽ học chi tiết ở bài sau

Truy Cập Phần Tử - Indexing

fruits = ["apple", "banana", "orange", "mango", "grape"]#          0        1         2         3        4       (positive)#         -5       -4        -3        -2       -1       (negative) # Positive indexingprint(fruits[0])   # appleprint(fruits[2])   # orange # Negative indexingprint(fruits[-1])  # grape (cuối)print(fruits[-2])  # mango # Access nested listmatrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]print(matrix[0])      # [1, 2, 3]print(matrix[0][0])   # 1print(matrix[1][2])   # 6

Lỗi phổ biến:

fruits = ["apple", "banana"]# print(fruits[5])  # IndexError: list index out of range # Cách an toànindex = 5if index < len(fruits):    print(fruits[index])else:    print("Index out of range")

Slicing - Cắt List

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # [start:stop]print(numbers[2:5])    # [2, 3, 4]print(numbers[:5])     # [0, 1, 2, 3, 4] (từ đầu)print(numbers[5:])     # [5, 6, 7, 8, 9] (đến cuối)print(numbers[:])      # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] (copy) # [start:stop:step]print(numbers[::2])    # [0, 2, 4, 6, 8] (mỗi 2)print(numbers[1::2])   # [1, 3, 5, 7, 9] (lẻ)print(numbers[::-1])   # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (đảo) # Negative indicesprint(numbers[-5:])    # [5, 6, 7, 8, 9]print(numbers[:-5])    # [0, 1, 2, 3, 4]

Ứng dụng:

# Lấy 3 phần tử đầutop_3 = ["Gold", "Silver", "Bronze", "4th", "5th"]print(top_3[:3])  # ['Gold', 'Silver', 'Bronze'] # Lấy 3 phần tử cuốiscores = [85, 90, 78, 92, 88]last_3 = scores[-3:]print(last_3)  # [78, 92, 88] # Copy listoriginal = [1, 2, 3]copy = original[:]  # Tạo copy mớicopy[0] = 999print(original)  # [1, 2, 3] (không đổi)print(copy)      # [999, 2, 3]

Thay Đổi Phần Tử

Thay đổi một phần tử

fruits = ["apple", "banana", "orange"] # Thay đổi theo indexfruits[1] = "mango"print(fruits)  # ['apple', 'mango', 'orange'] # Thay đổi phần tử cuốifruits[-1] = "grape"print(fruits)  # ['apple', 'mango', 'grape']

Thay đổi nhiều phần tử

numbers = [1, 2, 3, 4, 5] # Thay slicenumbers[1:3] = [20, 30]print(numbers)  # [1, 20, 30, 4, 5] # Thay bằng nhiều phần tử hơnnumbers[1:3] = [10, 20, 30, 40]print(numbers)  # [1, 10, 20, 30, 40, 4, 5] # Xóa bằng cách gán empty listnumbers[2:4] = []print(numbers)  # [1, 10, 40, 4, 5]

Thêm Phần Tử - Adding

1. append() - Thêm vào cuối

fruits = ["apple", "banana"] # Thêm một phần tửfruits.append("orange")print(fruits)  # ['apple', 'banana', 'orange'] # Thêm list (như một phần tử)fruits.append(["mango", "grape"])print(fruits)  # ['apple', 'banana', 'orange', ['mango', 'grape']]

2. extend() - Thêm nhiều phần tử

fruits = ["apple", "banana"] # Extend với listfruits.extend(["orange", "mango"])print(fruits)  # ['apple', 'banana', 'orange', 'mango'] # Extend với string (từng ký tự)fruits.extend("XY")print(fruits)  # ['apple', 'banana', 'orange', 'mango', 'X', 'Y'] # So sánh append vs extendlist1 = [1, 2]list1.append([3, 4])print(list1)  # [1, 2, [3, 4]] list2 = [1, 2]list2.extend([3, 4])print(list2)  # [1, 2, 3, 4]

3. insert() - Thêm vào vị trí

fruits = ["apple", "banana", "orange"] # Insert tại index 1fruits.insert(1, "mango")print(fruits)  # ['apple', 'mango', 'banana', 'orange'] # Insert ở đầufruits.insert(0, "grape")print(fruits)  # ['grape', 'apple', 'mango', 'banana', 'orange'] # Insert ở cuối (dùng append tốt hơn)fruits.insert(len(fruits), "kiwi")print(fruits)

4. Toán tử +

list1 = [1, 2, 3]list2 = [4, 5, 6] # Nối list (tạo list mới)result = list1 + list2print(result)  # [1, 2, 3, 4, 5, 6]print(list1)   # [1, 2, 3] (không đổi) # += (thay đổi list gốc)list1 += list2print(list1)  # [1, 2, 3, 4, 5, 6]

Xóa Phần Tử - Removing

1. remove() - Xóa theo giá trị

fruits = ["apple", "banana", "orange", "banana"] # Xóa phần tử đầu tiên tìm thấyfruits.remove("banana")print(fruits)  # ['apple', 'orange', 'banana'] # Lỗi nếu không tìm thấy# fruits.remove("grape")  # ValueError! # Cách an toànif "grape" in fruits:    fruits.remove("grape")

2. pop() - Xóa theo index

fruits = ["apple", "banana", "orange"] # Pop cuối (default)last = fruits.pop()print(last)    # orangeprint(fruits)  # ['apple', 'banana'] # Pop tại indexfirst = fruits.pop(0)print(first)   # appleprint(fruits)  # ['banana'] # Lỗi nếu index không hợp lệ# fruits.pop(10)  # IndexError!

3. del - Xóa theo index hoặc slice

numbers = [1, 2, 3, 4, 5] # Xóa tại indexdel numbers[2]print(numbers)  # [1, 2, 4, 5] # Xóa slicedel numbers[1:3]print(numbers)  # [1, 5] # Xóa toàn bộ list# del numbers# print(numbers)  # NameError!

4. clear() - Xóa tất cả

fruits = ["apple", "banana", "orange"] fruits.clear()print(fruits)  # []print(len(fruits))  # 0

So sánh:

# remove() - xóa theo giá trịitems = ["a", "b", "c"]items.remove("b")  # ['a', 'c'] # pop() - xóa theo index, trả về giá trịitems = ["a", "b", "c"]value = items.pop(1)  # value = "b", items = ['a', 'c'] # del - xóa theo index, không trả vềitems = ["a", "b", "c"]del items[1]  # items = ['a', 'c'] # clear() - xóa tất cảitems = ["a", "b", "c"]items.clear()  # items = []

List Methods Khác

1. index() - Tìm vị trí

fruits = ["apple", "banana", "orange", "banana"] # Tìm index đầu tiênpos = fruits.index("banana")print(pos)  # 1 # Tìm từ vị trí cụ thểpos2 = fruits.index("banana", 2)  # Tìm từ index 2print(pos2)  # 3 # Lỗi nếu không tìm thấy# fruits.index("grape")  # ValueError! # Cách an toànif "grape" in fruits:    pos = fruits.index("grape")else:    print("Not found")

2. count() - Đếm số lần xuất hiện

numbers = [1, 2, 2, 3, 2, 4, 2, 5] count = numbers.count(2)print(count)  # 4 # Đếm stringwords = ["hello", "world", "hello", "python"]print(words.count("hello"))  # 2

3. sort() - Sắp xếp

# Sort tăng dầnnumbers = [3, 1, 4, 1, 5, 9, 2]numbers.sort()print(numbers)  # [1, 1, 2, 3, 4, 5, 9] # Sort giảm dầnnumbers.sort(reverse=True)print(numbers)  # [9, 5, 4, 3, 2, 1, 1] # Sort stringsfruits = ["orange", "apple", "banana"]fruits.sort()print(fruits)  # ['apple', 'banana', 'orange'] # Sort theo lengthwords = ["python", "is", "awesome"]words.sort(key=len)print(words)  # ['is', 'python', 'awesome']

4. reverse() - Đảo ngược

numbers = [1, 2, 3, 4, 5] numbers.reverse()print(numbers)  # [5, 4, 3, 2, 1] # Hoặc dùng slicingnumbers2 = [1, 2, 3, 4, 5]reversed_list = numbers2[::-1]print(reversed_list)  # [5, 4, 3, 2, 1]

5. copy() - Sao chép

original = [1, 2, 3] # Shallow copy với copy()copy1 = original.copy()copy1[0] = 999print(original)  # [1, 2, 3] (không đổi)print(copy1)     # [999, 2, 3] # Copy với slicingcopy2 = original[:] # Copy với list()copy3 = list(original) # Reference (KHÔNG phải copy!)ref = originalref[0] = 999print(original)  # [999, 2, 3] (đã đổi!)

Ví Dụ Thực Tế

1. To-Do List Manager

# To-do listtodos = [] # Thêm tasktodos.append("Buy groceries")todos.append("Finish homework")todos.append("Call mom") print("To-Do List:")for i, task in enumerate(todos, 1):    print(f"{i}. {task}") # Hoàn thành taskcompleted = todos.pop(1)  # Xóa "Finish homework"print(f"\nCompleted: {completed}") # Thêm task mớitodos.insert(0, "Wake up early")  # Ưu tiên cao print("\nUpdated To-Do List:")for i, task in enumerate(todos, 1):    print(f"{i}. {task}")

2. Shopping Cart

# Shopping cartcart = [] # Thêm itemscart.append({"name": "Apple", "price": 2.5, "qty": 3})cart.append({"name": "Banana", "price": 1.5, "qty": 5})cart.append({"name": "Orange", "price": 3.0, "qty": 2}) # Display cartprint("Shopping Cart:")total = 0for item in cart:    subtotal = item["price"] * item["qty"]    total += subtotal    print(f"{item['name']:<10} x{item['qty']} = ${subtotal:.2f}") print(f"\nTotal: ${total:.2f}") # Remove itemcart.pop(1)  # Xóa Bananaprint("\nAfter removing Banana:", len(cart), "items")

3. Student Grade Manager

# Danh sách điểmgrades = [85, 90, 78, 92, 88, 76, 95] # Thống kêhighest = max(grades)lowest = min(grades)average = sum(grades) / len(grades)passing = len([g for g in grades if g >= 80]) print(f"Highest: {highest}")print(f"Lowest: {lowest}")print(f"Average: {average:.2f}")print(f"Passing (>=80): {passing}/{len(grades)}") # Sắp xếpgrades.sort(reverse=True)print(f"\nTop 3: {grades[:3]}")

Bài Tập Thực Hành

Bài 1: List Operations

Tạo list numbers = [10, 20, 30, 40, 50]:

  • Thêm 60 vào cuối
  • Thêm 5 vào đầu
  • Xóa 30
  • In list đảo ngược

Bài 2: Unique Items

Viết chương trình xóa phần tử trùng lặp trong list:

  • Input: [1, 2, 2, 3, 4, 4, 5]
  • Output: [1, 2, 3, 4, 5]

Bài 3: List Statistics

Cho list số, tính:

  • Tổng
  • Trung bình
  • Max, Min
  • Số chẵn, lẻ

Bài 4: Shopping List

Tạo shopping list app:

  • Add item
  • Remove item
  • Show all items
  • Clear all

Bài 5: Merge Sorted Lists

Gộp 2 sorted lists thành 1 sorted list:

  • list1 = [1, 3, 5]
  • list2 = [2, 4, 6]
  • Output: [1, 2, 3, 4, 5, 6]

Tóm Tắt

✅ List là collection có thứ tự, mutable
✅ Tạo list: [], list(), list comprehension
✅ Indexing: list[0], list[-1]
✅ Slicing: list[start:stop:step]
✅ Thêm: append(), extend(), insert(), +
✅ Xóa: remove(), pop(), del, clear()
✅ Methods: index(), count(), sort(), reverse(), copy()

Bài Tiếp Theo

Bài 5.2: Lists (Phần 2) - List comprehension, nested lists, sorting nâng cao, và list trong thực tế.


Remember:

  • Lists are mutable (có thể thay đổi)
  • Indexing bắt đầu từ 0
  • append() vs extend() vs insert()
  • remove() vs pop() vs del vs clear()
  • Slicing tạo copy mới, reference thì không!