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()vàmap(): list comprehension thường dễ đọc hơn- Practice, practice, practice!