Bài 5.2: Lists - Danh Sách (Phần 2)

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

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

  • ✅ Sử dụng list comprehension hiệu quả
  • ✅ Làm việc với nested lists (2D lists)
  • ✅ Sorting nâng cao với key và lambda
  • ✅ Sử dụng filter(), map() với lists
  • ✅ Áp dụng các kỹ thuật xử lý list thực tế

List Comprehension

List comprehension là cách ngắn gọn để tạo list mới từ iterable.

Cú Pháp Cơ Bản

# Cách thông thườngsquares = []for x in range(5):    squares.append(x**2)print(squares)  # [0, 1, 4, 9, 16] # List comprehension (ngắn gọn hơn)squares = [x**2 for x in range(5)]print(squares)  # [0, 1, 4, 9, 16] # Syntax: [expression for item in iterable]

Với Điều Kiện (if)

# Lọc số chẵnevens = [x for x in range(10) if x % 2 == 0]print(evens)  # [0, 2, 4, 6, 8] # Lọc số lớn hơn 5numbers = [1, 8, 3, 9, 2, 7, 4]large = [x for x in numbers if x > 5]print(large)  # [8, 9, 7] # Lọc string dài hơn 5 ký tựwords = ["python", "is", "awesome", "and", "powerful"]long_words = [w for w in words if len(w) > 5]print(long_words)  # ['python', 'awesome', 'powerful']

Với if-else

# Chẵn thì bình phương, lẻ thì nhân 3result = [x**2 if x % 2 == 0 else x*3 for x in range(6)]print(result)  # [0, 3, 4, 9, 16, 15] # Convert nhiệt độ: dương giữ nguyên, âm thành 0temps = [25, -5, 30, -10, 15]adjusted = [t if t > 0 else 0 for t in temps]print(adjusted)  # [25, 0, 30, 0, 15] # Syntax: [expr_if_true if condition else expr_if_false for item in iterable]

Nested List Comprehension

# 2D listmatrix = [[i*j for j in range(1, 4)] for i in range(1, 4)]print(matrix)# [[1, 2, 3],#  [2, 4, 6],#  [3, 6, 9]] # Flatten 2D listmatrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]flat = [num for row in matrix for num in row]print(flat)  # [1, 2, 3, 4, 5, 6, 7, 8, 9] # Với điều kiệnpairs = [(x, y) for x in range(3) for y in range(3) if x != y]print(pairs)# [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)]

Ví Dụ Thực Tế

# 1. Extract emailsusers = [    {"name": "Alice", "email": "[email protected]"},    {"name": "Bob", "email": "[email protected]"},    {"name": "Charlie", "email": "[email protected]"}]emails = [user["email"] for user in users]print(emails) # 2. Uppercase namesnames = ["alice", "bob", "charlie"]upper_names = [name.upper() for name in names]print(upper_names)  # ['ALICE', 'BOB', 'CHARLIE'] # 3. Extract numbers from stringsdata = ["apple123", "banana456", "orange789"]numbers = [int(''.join(c for c in s if c.isdigit())) for s in data]print(numbers)  # [123, 456, 789] # 4. Filter và transformprices = [100, 200, 50, 300, 150]discounted = [p * 0.9 for p in prices if p > 100]print(discounted)  # [180.0, 270.0, 135.0] # 5. Create range with stepmultiples_of_3 = [i for i in range(30) if i % 3 == 0]print(multiples_of_3)  # [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]

Nested Lists (2D Lists)

Nested list là list chứa list khác (như ma trận 2D).

Tạo Nested Lists

# Cách 1: Manualmatrix = [    [1, 2, 3],    [4, 5, 6],    [7, 8, 9]] # Cách 2: List comprehensionrows, cols = 3, 4matrix = [[0 for j in range(cols)] for i in range(rows)]print(matrix)# [[0, 0, 0, 0],#  [0, 0, 0, 0],#  [0, 0, 0, 0]] # ⚠️ TRÁNH: Tạo sai cách (reference giống nhau)wrong = [[0] * 3] * 3  # WRONG!wrong[0][0] = 1print(wrong)  # [[1, 0, 0], [1, 0, 0], [1, 0, 0]] - Tất cả đổi! # ✅ ĐÚNG: Mỗi row là object riêngcorrect = [[0] * 3 for _ in range(3)]correct[0][0] = 1print(correct)  # [[1, 0, 0], [0, 0, 0], [0, 0, 0]] - Chỉ row đầu đổi

Truy Cập Nested Lists

matrix = [    [1, 2, 3],    [4, 5, 6],    [7, 8, 9]] # Truy cập phần tửprint(matrix[0])      # [1, 2, 3] (row đầu)print(matrix[0][0])   # 1print(matrix[1][2])   # 6print(matrix[-1][-1]) # 9 (phần tử cuối) # Thay đổi phần tửmatrix[1][1] = 50print(matrix)  # [[1, 2, 3], [4, 50, 6], [7, 8, 9]] # Iteratefor row in matrix:    for num in row:        print(num, end=' ')    print()  # Newline sau mỗi row

Operations với Nested Lists

matrix = [    [1, 2, 3],    [4, 5, 6],    [7, 8, 9]] # Lấy columncol_0 = [row[0] for row in matrix]print(col_0)  # [1, 4, 7] col_2 = [row[2] for row in matrix]print(col_2)  # [3, 6, 9] # Transpose (chuyển vị)transposed = [[row[i] for row in matrix] for i in range(len(matrix[0]))]print(transposed)# [[1, 4, 7],#  [2, 5, 8],#  [3, 6, 9]] # Sum mỗi rowrow_sums = [sum(row) for row in matrix]print(row_sums)  # [6, 15, 24] # Sum mỗi columncol_sums = [sum(row[i] for row in matrix) for i in range(len(matrix[0]))]print(col_sums)  # [12, 15, 18] # Flattenflat = [num for row in matrix for num in row]print(flat)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Ví Dụ Thực Tế - Bảng Điểm

# Bảng điểm: [Toán, Lý, Hóa]grades = [    [8, 7, 9],   # Student 1    [9, 8, 8],   # Student 2    [7, 9, 7],   # Student 3    [10, 9, 9]   # Student 4] # Điểm trung bình từng học sinhstudent_avgs = [sum(student) / len(student) for student in grades]print("Student averages:", student_avgs)# [8.0, 8.33, 7.67, 9.33] # Điểm trung bình từng mônsubject_avgs = [sum(grades[i][j] for i in range(len(grades))) / len(grades)                 for j in range(len(grades[0]))]print("Subject averages:", subject_avgs)# [8.5, 8.25, 8.25] # Học sinh có điểm TB cao nhấtbest_student = student_avgs.index(max(student_avgs))print(f"Best student: Student {best_student + 1}") # Môn khó nhất (điểm TB thấp nhất)subjects = ["Math", "Physics", "Chemistry"]hardest_idx = subject_avgs.index(min(subject_avgs))print(f"Hardest subject: {subjects[hardest_idx]}")

Sorting Nâng Cao

sort() vs sorted()

numbers = [3, 1, 4, 1, 5, 9, 2] # sort() - sắp xếp tại chỗ (in-place), trả về Nonenumbers.sort()print(numbers)  # [1, 1, 2, 3, 4, 5, 9] # sorted() - tạo list mới, không đổi originalnumbers2 = [3, 1, 4, 1, 5, 9, 2]sorted_nums = sorted(numbers2)print(numbers2)      # [3, 1, 4, 1, 5, 9, 2] (không đổi)print(sorted_nums)   # [1, 1, 2, 3, 4, 5, 9] (list mới)

Sorting với key

# Sort theo lengthwords = ["python", "is", "awesome", "and", "powerful"]words.sort(key=len)print(words)  # ['is', 'and', 'python', 'awesome', 'powerful'] # Sort theo ký tự cuốiwords2 = ["apple", "banana", "cherry", "date"]words2.sort(key=lambda x: x[-1])print(words2)  # ['apple', 'banana', 'date', 'cherry'] # Sort số theo absolute valuenumbers = [-5, 3, -1, 8, -10]numbers.sort(key=abs)print(numbers)  # [-1, 3, -5, 8, -10]

Sorting Objects

# List of dictionariesstudents = [    {"name": "Alice", "age": 25, "grade": 85},    {"name": "Bob", "age": 22, "grade": 90},    {"name": "Charlie", "age": 23, "grade": 88}] # Sort theo agestudents.sort(key=lambda x: x["age"])for s in students:    print(f"{s['name']}: {s['age']}")# Bob: 22# Charlie: 23# Alice: 25 # Sort theo grade (giảm dần)students.sort(key=lambda x: x["grade"], reverse=True)for s in students:    print(f"{s['name']}: {s['grade']}")# Bob: 90# Charlie: 88# Alice: 85 # Sort theo nhiều tiêu chí (grade giảm, age tăng)students.sort(key=lambda x: (-x["grade"], x["age"]))

Custom Sorting

# Sort string không phân biệt hoa/thườngwords = ["Python", "apple", "Banana", "cherry"]words.sort(key=str.lower)print(words)  # ['apple', 'Banana', 'cherry', 'Python'] # Sort theo custom ruledef sort_priority(item):    """Số chẵn trước, sau đó theo giá trị"""    is_even = 0 if item % 2 == 0 else 1    return (is_even, item) numbers = [5, 2, 8, 1, 9, 4, 7, 3, 6]numbers.sort(key=sort_priority)print(numbers)  # [2, 4, 6, 8, 1, 3, 5, 7, 9]

Lambda Functions với Lists

Lambda là anonymous function (hàm không tên) ngắn gọn.

# Syntax: lambda arguments: expression # So sánh function thông thường vs lambdadef square(x):    return x ** 2 square_lambda = lambda x: x ** 2 print(square(5))         # 25print(square_lambda(5))  # 25 # Dùng với sorted()numbers = [5, 2, 8, 1, 9]sorted_nums = sorted(numbers, key=lambda x: -x)  # Giảm dầnprint(sorted_nums)  # [9, 8, 5, 2, 1] # Dùng với list comprehensionpoints = [(1, 5), (3, 2), (2, 8), (4, 1)]sorted_by_y = sorted(points, key=lambda p: p[1])print(sorted_by_y)  # [(4, 1), (3, 2), (1, 5), (2, 8)]

filter() và map()

filter() - Lọc phần tử

# Syntax: filter(function, iterable) numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Lọc số chẵnevens = list(filter(lambda x: x % 2 == 0, numbers))print(evens)  # [2, 4, 6, 8, 10] # Tương đương list comprehensionevens2 = [x for x in numbers if x % 2 == 0] # Lọc string dàiwords = ["a", "ab", "abc", "abcd", "abcde"]long_words = list(filter(lambda w: len(w) > 2, words))print(long_words)  # ['abc', 'abcd', 'abcde'] # Lọc None và emptydata = [0, 1, "", "text", None, [], [1, 2], False, True]filtered = list(filter(None, data))  # Lọc falsy valuesprint(filtered)  # [1, 'text', [1, 2], True]

map() - Transform phần tử

# Syntax: map(function, iterable) numbers = [1, 2, 3, 4, 5] # Bình phươngsquares = list(map(lambda x: x**2, numbers))print(squares)  # [1, 4, 9, 16, 25] # Tương đương list comprehensionsquares2 = [x**2 for x in numbers] # Uppercase stringsnames = ["alice", "bob", "charlie"]upper = list(map(str.upper, names))print(upper)  # ['ALICE', 'BOB', 'CHARLIE'] # Map với nhiều iterablesnums1 = [1, 2, 3]nums2 = [4, 5, 6]products = list(map(lambda x, y: x * y, nums1, nums2))print(products)  # [4, 10, 18]

Kết hợp filter() và map()

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Bình phương các số chẵnresult = list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, numbers)))print(result)  # [4, 16, 36, 64, 100] # Tương đương list comprehension (dễ đọc hơn)result2 = [x**2 for x in numbers if x % 2 == 0]print(result2)  # [4, 16, 36, 64, 100]

List Unpacking

# Basic unpackinga, b, c = [1, 2, 3]print(a, b, c)  # 1 2 3 # Unpacking với *first, *middle, last = [1, 2, 3, 4, 5]print(first)   # 1print(middle)  # [2, 3, 4]print(last)    # 5 # Skip values với _first, _, third, *_ = [1, 2, 3, 4, 5]print(first, third)  # 1 3 # Swap variablesa, b = 10, 20a, b = b, a  # Swapprint(a, b)  # 20 10 # Function với unpackingdef calculate(a, b, c):    return a + b * c nums = [2, 3, 4]result = calculate(*nums)  # Unpack list thành argumentsprint(result)  # 14

Ví Dụ Thực Tế

1. Data Processing Pipeline

# Raw dataraw_data = [    "  Alice, 25, 85  ",    "  Bob, 22, 90  ",    "  Charlie, 23, 88  ",    "  Diana, 24, 92  "] # Process: trim -> split -> convert types -> create dictstudents = []for line in raw_data:    parts = line.strip().split(', ')    student = {        "name": parts[0],        "age": int(parts[1]),        "grade": int(parts[2])    }    students.append(student) # Hoặc dùng list comprehensionstudents2 = [    {"name": parts[0], "age": int(parts[1]), "grade": int(parts[2])}    for parts in [line.strip().split(', ') for line in raw_data]] # Filter: grade >= 90top_students = [s for s in students if s["grade"] >= 90]print("Top students:", [s["name"] for s in top_students]) # Sort by grade (descending)students.sort(key=lambda x: x["grade"], reverse=True)print("Ranking:")for i, s in enumerate(students, 1):    print(f"{i}. {s['name']}: {s['grade']}")

2. Matrix Operations

# Matrix calculatordef print_matrix(matrix, name="Matrix"):    """Pretty print matrix"""    print(f"\n{name}:")    for row in matrix:        print("  [" + " ".join(f"{x:4}" for x in row) + "]") # Create matricesA = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]B = [[9, 8, 7], [6, 5, 4], [3, 2, 1]] print_matrix(A, "Matrix A")print_matrix(B, "Matrix B") # Add matricesC = [[A[i][j] + B[i][j] for j in range(len(A[0]))] for i in range(len(A))]print_matrix(C, "A + B") # Multiply by scalarscalar = 2D = [[x * scalar for x in row] for row in A]print_matrix(D, "A * 2") # Diagonal sumdiagonal_sum = sum(A[i][i] for i in range(len(A)))print(f"\nDiagonal sum: {diagonal_sum}")

3. Text Analyzer

text = """Python is an amazing programming language.It is easy to learn and powerful to use.Python is widely used in data science and web development.""" # Processwords = text.lower().split()words = [w.strip('.,!?') for w in words]  # Remove punctuation # Word frequencyword_freq = {}for word in words:    word_freq[word] = word_freq.get(word, 0) + 1 # Sort by frequencysorted_words = sorted(word_freq.items(), key=lambda x: x[1], reverse=True) print("Top 5 words:")for word, count in sorted_words[:5]:    print(f"  {word}: {count}") # Words longer than 5 charslong_words = [w for w in set(words) if len(w) > 5]print(f"\nLong words ({len(long_words)}): {sorted(long_words)}")

4. Shopping Cart System

# Productsproducts = [    {"id": 1, "name": "Laptop", "price": 1000, "stock": 5},    {"id": 2, "name": "Mouse", "price": 25, "stock": 20},    {"id": 3, "name": "Keyboard", "price": 75, "stock": 15},    {"id": 4, "name": "Monitor", "price": 300, "stock": 8}] # Cartcart = [    {"product_id": 1, "quantity": 1},    {"product_id": 2, "quantity": 2},    {"product_id": 3, "quantity": 1}] # Calculate totaltotal = 0print("Cart:")for item in cart:    product = next(p for p in products if p["id"] == item["product_id"])    subtotal = product["price"] * item["quantity"]    total += subtotal    print(f"  {product['name']:<15} x{item['quantity']} = ${subtotal:>7.2f}") print(f"\nTotal: ${total:.2f}") # Apply discount (10% if total > 500)if total > 500:    discount = total * 0.1    final = total - discount    print(f"Discount (10%): -${discount:.2f}")    print(f"Final: ${final:.2f}")

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

Bài 1: List Comprehension

Sử dụng list comprehension:

  • Tạo list các số chia hết cho 3 và 5 từ 1-100
  • Tạo list các số nguyên tố từ 1-50
  • Tạo list [1, -1, 2, -2, 3, -3, 4, -4, 5, -5]

Bài 2: Matrix Operations

Cho 2 ma trận 3x3:

  • Cộng 2 ma trận
  • Nhân ma trận với scalar
  • Tìm max/min của từng row và column
  • Transpose ma trận

Bài 3: Student Grade System

Tạo hệ thống quản lý điểm:

  • List students với name, grades [3 môn]
  • Tính điểm TB từng student
  • Xếp hạng students
  • Tìm môn khó nhất
  • Filter students pass (TB >= 5)

Bài 4: Data Filtering

Cho list mixed data, filter:

  • Chỉ numbers
  • Chỉ strings
  • Chỉ lists
  • Remove duplicates

Bài 5: Text Processing

Cho đoạn text:

  • Đếm word frequency
  • Tìm 10 từ xuất hiện nhiều nhất
  • Tìm longest word
  • Remove stop words ("a", "an", "the", "is", "in", "on")

Tóm Tắt

✅ List comprehension: [expr for item in iterable if condition]
✅ Nested lists: Matrix operations, 2D data
✅ Sorting: sort() vs sorted(), key parameter
✅ Lambda: lambda args: expression
filter(): Lọc phần tử
map(): Transform phần tử
✅ List comprehension > filter/map (readable)

Bài Tiếp Theo

Bài 6: Tuples - Immutable sequences, tuple packing/unpacking, và khi nào dùng tuple.


Remember:

  • List comprehension: ngắn gọn, dễ đọc, nhanh hơn loop
  • Nested lists: cẩn thận với reference vs copy
  • Lambda: tốt cho simple functions, phức tạp thì dùng def
  • filter()map(): list comprehension thường dễ đọc hơn
  • Practice, practice, practice!