Vòng lặp lồng nhau và Control Flow
Vòng lặp lồng nhau (nested loops) là khi một vòng lặp nằm bên trong vòng lặp khác. Đây là kỹ thuật quan trọng khi làm việc với dữ liệu đa chiều như ma trận, bảng, hoặc các cấu trúc phức tạp.
1. Vòng lặp lồng nhau cơ bản
For loop lồng nhau
# Vòng lặp 2 cấp đơn giản
for i in range(3):
for j in range(3):
print(f"i={i}, j={j}")
# Kết quả:
# i=0, j=0
# i=0, j=1
# i=0, j=2
# i=1, j=0
# i=1, j=1
# i=1, j=2
# i=2, j=0
# i=2, j=1
# i=2, j=2While loop lồng nhau
# While lồng nhau
i = 0
while i < 3:
j = 0
while j < 3:
print(f"i={i}, j={j}")
j += 1
i += 1
# Kết quả tương tự như for loop trênKết hợp for và while
# For bên ngoài, while bên trong
for i in range(3):
j = 0
while j < 3:
print(f"({i}, {j})", end=" ")
j += 1
print() # Xuống dòng
# Kết quả:
# (0, 0) (0, 1) (0, 2)
# (1, 0) (1, 1) (1, 2)
# (2, 0) (2, 1) (2, 2)2. In hình và pattern
In hình chữ nhật
# In hình chữ nhật 4x6
rows = 4
cols = 6
for i in range(rows):
for j in range(cols):
print("*", end=" ")
print() # Xuống dòng sau mỗi hàng
# Kết quả:
# * * * * * *
# * * * * * *
# * * * * * *
# * * * * * *In tam giác vuông
# Tam giác vuông tăng dần
n = 5
for i in range(1, n + 1):
for j in range(i):
print("*", end=" ")
print()
# Kết quả:
# *
# * *
# * * *
# * * * *
# * * * * *
# Tam giác vuông giảm dần
for i in range(n, 0, -1):
for j in range(i):
print("*", end=" ")
print()
# Kết quả:
# * * * * *
# * * * *
# * * *
# * *
# *In tam giác cân
n = 5
# Tam giác cân
for i in range(1, n + 1):
# In khoảng trắng
for j in range(n - i):
print(" ", end=" ")
# In dấu sao
for j in range(2 * i - 1):
print("*", end=" ")
print()
# Kết quả:
# *
# * * *
# * * * * *
# * * * * * * *
# * * * * * * * * *In hình thoi
n = 5
# Nửa trên (bao gồm giữa)
for i in range(1, n + 1):
for j in range(n - i):
print(" ", end=" ")
for j in range(2 * i - 1):
print("*", end=" ")
print()
# Nửa dưới
for i in range(n - 1, 0, -1):
for j in range(n - i):
print(" ", end=" ")
for j in range(2 * i - 1):
print("*", end=" ")
print()
# Kết quả:
# *
# * * *
# * * * * *
# * * * * * * *
# * * * * * * * * *
# * * * * * * *
# * * * * *
# * * *
# *In bảng số
# Bảng nhân
for i in range(1, 6):
for j in range(1, 6):
print(f"{i * j:3}", end=" ")
print()
# Kết quả:
# 1 2 3 4 5
# 2 4 6 8 10
# 3 6 9 12 15
# 4 8 12 16 20
# 5 10 15 20 253. Làm việc với List 2D (Ma trận)
Tạo ma trận
# Tạo ma trận 3x4 với giá trị 0
rows = 3
cols = 4
matrix = []
for i in range(rows):
row = []
for j in range(cols):
row.append(0)
matrix.append(row)
print(matrix)
# [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
# Cách ngắn gọn với list comprehension
matrix = [[0 for j in range(cols)] for i in range(rows)]
print(matrix)Duyệt ma trận
# Ma trận ví dụ
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# Duyệt qua từng phần tử
for i in range(len(matrix)):
for j in range(len(matrix[i])):
print(f"matrix[{i}][{j}] = {matrix[i][j]}")
# Kết quả:
# matrix[0][0] = 1
# matrix[0][1] = 2
# ...
# matrix[2][2] = 9
# Cách khác với enumerate
for i, row in enumerate(matrix):
for j, value in enumerate(row):
print(f"matrix[{i}][{j}] = {value}")In ma trận đẹp
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]
# In ma trận
for row in matrix:
for value in row:
print(f"{value:3}", end=" ")
print()
# Kết quả:
# 1 2 3 4
# 5 6 7 8
# 9 10 11 12Tính tổng các phần tử
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# Tổng tất cả phần tử
total = 0
for row in matrix:
for value in row:
total += value
print(f"Tổng: {total}") # Tổng: 45
# Tổng từng hàng
for i, row in enumerate(matrix):
row_sum = sum(row)
print(f"Tổng hàng {i}: {row_sum}")
# Tổng từng cột
cols = len(matrix[0])
for j in range(cols):
col_sum = 0
for i in range(len(matrix)):
col_sum += matrix[i][j]
print(f"Tổng cột {j}: {col_sum}")4. Break trong vòng lặp lồng nhau
Break chỉ thoát vòng lặp trong cùng
# Break chỉ thoát vòng lặp j
for i in range(3):
print(f"Vòng lặp i = {i}")
for j in range(5):
if j == 2:
print(f" Break tại j = {j}")
break
print(f" j = {j}")
# Kết quả:
# Vòng lặp i = 0
# j = 0
# j = 1
# Break tại j = 2
# Vòng lặp i = 1
# j = 0
# j = 1
# Break tại j = 2
# Vòng lặp i = 2
# j = 0
# j = 1
# Break tại j = 2Thoát cả hai vòng lặp với flag
# Sử dụng biến cờ (flag)
found = False
for i in range(5):
for j in range(5):
if i * j == 12:
print(f"Tìm thấy tại i={i}, j={j}")
found = True
break
if found:
break
# Kết quả: Tìm thấy tại i=3, j=4Thoát với else clause
# else của for chỉ chạy khi KHÔNG có break
for i in range(3):
for j in range(3):
if i == 1 and j == 1:
print(f"Break tại i={i}, j={j}")
break
else:
continue # Tiếp tục vòng lặp i
break # Chỉ chạy khi có break ở vòng j
print("Đã thoát vòng lặp")Sử dụng function để thoát
# Dùng return để thoát cả hai vòng lặp
def find_pair_sum(matrix, target):
for i in range(len(matrix)):
for j in range(len(matrix[i])):
if matrix[i][j] == target:
return (i, j) # Thoát ngay lập tức
return None # Không tìm thấy
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
result = find_pair_sum(matrix, 5)
print(result) # (1, 1)5. Continue trong vòng lặp lồng nhau
Continue chỉ bỏ qua lần lặp hiện tại
# Continue bỏ qua phần còn lại của vòng lặp trong cùng
for i in range(3):
for j in range(5):
if j == 2:
continue # Bỏ qua j=2, tiếp tục j=3
print(f"i={i}, j={j}", end=" ")
print()
# Kết quả:
# i=0, j=0 i=0, j=1 i=0, j=3 i=0, j=4
# i=1, j=0 i=1, j=1 i=1, j=3 i=1, j=4
# i=2, j=0 i=2, j=1 i=2, j=3 i=2, j=4Bỏ qua đường chéo của ma trận
# In ma trận nhưng bỏ qua đường chéo chính
n = 5
for i in range(n):
for j in range(n):
if i == j:
print(".", end=" ")
continue
print("*", end=" ")
print()
# Kết quả:
# . * * * *
# * . * * *
# * * . * *
# * * * . *
# * * * * .6. Ví dụ thực tế
Tìm kiếm trong list 2D
# Tìm vị trí của một giá trị trong ma trận
def find_value(matrix, target):
for i in range(len(matrix)):
for j in range(len(matrix[i])):
if matrix[i][j] == target:
return (i, j)
return None
data = [
[10, 20, 30],
[40, 50, 60],
[70, 80, 90]
]
position = find_value(data, 50)
if position:
print(f"Tìm thấy tại vị trí {position}") # Tìm thấy tại vị trí (1, 1)
else:
print("Không tìm thấy")Chuyển vị ma trận (Transpose)
# Ma trận gốc
matrix = [
[1, 2, 3],
[4, 5, 6]
]
# Tạo ma trận chuyển vị
rows = len(matrix)
cols = len(matrix[0])
transpose = []
for j in range(cols):
new_row = []
for i in range(rows):
new_row.append(matrix[i][j])
transpose.append(new_row)
print("Ma trận gốc:")
for row in matrix:
print(row)
print("\nMa trận chuyển vị:")
for row in transpose:
print(row)
# Kết quả:
# Ma trận gốc:
# [1, 2, 3]
# [4, 5, 6]
#
# Ma trận chuyển vị:
# [1, 4]
# [2, 5]
# [3, 6]Nhân hai ma trận
# Nhân ma trận A (2x3) với B (3x2)
A = [
[1, 2, 3],
[4, 5, 6]
]
B = [
[7, 8],
[9, 10],
[11, 12]
]
# Kích thước kết quả: (rows của A) x (cols của B)
rows_A = len(A)
cols_A = len(A[0])
cols_B = len(B[0])
# Tạo ma trận kết quả
result = [[0 for j in range(cols_B)] for i in range(rows_A)]
# Nhân ma trận
for i in range(rows_A):
for j in range(cols_B):
for k in range(cols_A):
result[i][j] += A[i][k] * B[k][j]
print("Kết quả A × B:")
for row in result:
print(row)
# Kết quả:
# [58, 64]
# [139, 154]Bàn cờ vua
# Tạo bàn cờ vua 8x8
def create_chess_board():
for i in range(8):
for j in range(8):
if (i + j) % 2 == 0:
print("⬜", end=" ")
else:
print("⬛", end=" ")
print()
create_chess_board()
# Kết quả: Bàn cờ đen trắng xen kẽSudoku validator
# Kiểm tra hàng Sudoku có hợp lệ không
def is_valid_row(board, row):
seen = set()
for j in range(9):
value = board[row][j]
if value != 0:
if value in seen:
return False
seen.add(value)
return True
# Kiểm tra cột Sudoku có hợp lệ không
def is_valid_col(board, col):
seen = set()
for i in range(9):
value = board[i][col]
if value != 0:
if value in seen:
return False
seen.add(value)
return True
# Kiểm tra toàn bộ Sudoku
def is_valid_sudoku(board):
# Kiểm tra tất cả hàng
for i in range(9):
if not is_valid_row(board, i):
return False
# Kiểm tra tất cả cột
for j in range(9):
if not is_valid_col(board, j):
return False
return True
# Test
sudoku = [
[5, 3, 0, 0, 7, 0, 0, 0, 0],
[6, 0, 0, 1, 9, 5, 0, 0, 0],
[0, 9, 8, 0, 0, 0, 0, 6, 0],
[8, 0, 0, 0, 6, 0, 0, 0, 3],
[4, 0, 0, 8, 0, 3, 0, 0, 1],
[7, 0, 0, 0, 2, 0, 0, 0, 6],
[0, 6, 0, 0, 0, 0, 2, 8, 0],
[0, 0, 0, 4, 1, 9, 0, 0, 5],
[0, 0, 0, 0, 8, 0, 0, 7, 9]
]
print(is_valid_sudoku(sudoku)) # TrueTạo bảng lịch
# Tạo lịch tháng
def print_calendar(days, start_day):
"""
days: số ngày trong tháng
start_day: ngày bắt đầu (0=Chủ nhật, 1=Thứ 2, ...)
"""
print("CN T2 T3 T4 T5 T6 T7")
print("-" * 28)
# In khoảng trống cho các ngày trước ngày đầu tháng
for i in range(start_day):
print(" ", end="")
# In các ngày trong tháng
for day in range(1, days + 1):
print(f"{day:2} ", end="")
# Xuống dòng sau thứ 7
if (day + start_day) % 7 == 0:
print()
print() # Xuống dòng cuối
# Tháng 12/2024: 31 ngày, bắt đầu từ CN (0)
print("Tháng 12/2024")
print_calendar(31, 0)7. Best Practices
✅ NÊN làm
# 1. Sử dụng enumerate khi cần index
matrix = [[1, 2], [3, 4]]
for i, row in enumerate(matrix):
for j, value in enumerate(row):
print(f"[{i}][{j}] = {value}")
# 2. Sử dụng list comprehension cho ma trận đơn giản
matrix = [[i * j for j in range(5)] for i in range(5)]
# 3. Tách logic phức tạp thành functions
def process_matrix(matrix):
for row in matrix:
for value in row:
# Process value
pass
# 4. Đặt tên biến rõ ràng
for row_index in range(len(matrix)):
for col_index in range(len(matrix[row_index])):
value = matrix[row_index][col_index]❌ KHÔNG NÊN làm
# 1. Tránh lồng quá nhiều cấp (> 3 cấp)
# ❌ KHÔNG TỐT
for i in range(n):
for j in range(n):
for k in range(n):
for l in range(n): # Quá nhiều!
# ...
# 2. Tránh logic phức tạp trong vòng lặp
# ❌ KHÔNG TỐT
for i in range(len(matrix)):
for j in range(len(matrix[i])):
if complex_condition_1 and complex_condition_2:
if another_condition:
# Quá phức tạp!
# ✅ TỐT HƠN - Tách thành function
def should_process(i, j, value):
return complex_condition_1 and complex_condition_2 and another_condition
for i, row in enumerate(matrix):
for j, value in enumerate(row):
if should_process(i, j, value):
# ProcessTổng kết
- Nested loops: Vòng lặp bên trong vòng lặp khác
- Break: Thoát khỏi vòng lặp trong cùng
- Continue: Bỏ qua phần còn lại, chuyển sang lần lặp tiếp theo
- Ứng dụng:
- In hình và patterns
- Ma trận 2D
- Bảng và lịch
- Tìm kiếm trong dữ liệu đa chiều
- Best practices:
- Giới hạn độ sâu lồng nhau (tối đa 2-3 cấp)
- Sử dụng enumerate khi cần index
- Tách logic phức tạp thành functions
- Đặt tên biến rõ ràng
- Cân nhắc list comprehension cho code ngắn gọn hơn
Last updated on
Python