Sửa list trong khi đang iterate
Hiện tượng lạ
Phần tiêu đề “Hiện tượng lạ”numbers = [1, 2, 3, 4, 5]
# Xóa số chẵnfor num in numbers: if num % 2 == 0: numbers.remove(num)
print(numbers) # [1, 3, 5] ❌ Thiếu số 4?!# Thực tế: [1, 3, 5] hoặc [1, 2, 3, 5] tùy implementationWhat the Python?! Tại sao skip items?! 😱
Giải thích
Phần tiêu đề “Giải thích”Iterator bị lỗi khi list thay đổi
Phần tiêu đề “Iterator bị lỗi khi list thay đổi”numbers = [1, 2, 3, 4]
for i, num in enumerate(numbers): print(f"Index {i}: {num}") if num == 2: numbers.remove(2) # Xóa → Indexes shift!
# Index 0: 1# Index 1: 2# Index 2: 4 ← Skip 3!Giải pháp
Phần tiêu đề “Giải pháp”✅ Solution 1: Iterate qua copy
Phần tiêu đề “✅ Solution 1: Iterate qua copy”numbers = [1, 2, 3, 4, 5]
# Iterate qua copy, modify originalfor num in numbers.copy(): # or numbers[:] if num % 2 == 0: numbers.remove(num)
print(numbers) # [1, 3, 5] ✅✅ Solution 2: List comprehension
Phần tiêu đề “✅ Solution 2: List comprehension”numbers = [1, 2, 3, 4, 5]
# Tạo list mớinumbers = [num for num in numbers if num % 2 != 0]
print(numbers) # [1, 3, 5] ✅✅ Solution 3: filter()
Phần tiêu đề “✅ Solution 3: filter()”numbers = [1, 2, 3, 4, 5]
numbers = list(filter(lambda x: x % 2 != 0, numbers))
print(numbers) # [1, 3, 5] ✅✅ Solution 4: Iterate ngược
Phần tiêu đề “✅ Solution 4: Iterate ngược”numbers = [1, 2, 3, 4, 5]
# Iterate từ cuối → đầufor i in range(len(numbers) - 1, -1, -1): if numbers[i] % 2 == 0: del numbers[i]
print(numbers) # [1, 3, 5] ✅Với dictionary
Phần tiêu đề “Với dictionary”# ❌ SAIdata = {"a": 1, "b": 2, "c": 3}for key in data: if data[key] % 2 == 0: del data[key] # RuntimeError!
# ✅ ĐÚNGdata = {"a": 1, "b": 2, "c": 3}for key in list(data.keys()): # Copy keys if data[key] % 2 == 0: del data[key]Tóm tắt
Phần tiêu đề “Tóm tắt”Không modify collection khi đang iterate!
- ❌ Gây skip items hoặc RuntimeError
- ✅ Iterate qua copy
- ✅ List comprehension
- ✅ Iterate ngược
Pattern:
# Iterate qua copyfor item in items.copy(): if condition: items.remove(item)
# List comprehensionitems = [x for x in items if not condition]