Generator exhaustion - Dùng 1 lần rồi... hết!
Hiện tượng lạ
Phần tiêu đề “Hiện tượng lạ”gen = (x for x in range(5))
# Lần 1print(list(gen)) # [0, 1, 2, 3, 4] ✅
# Lần 2print(list(gen)) # [] ❌ Rỗng?!What the Python?! Generator dùng 1 lần rồi hết?! 😱
Giải thích
Phần tiêu đề “Giải thích”Generator là iterator, chỉ dùng 1 lần
Phần tiêu đề “Generator là iterator, chỉ dùng 1 lần”gen = (x for x in range(3))
# Iterate lần 1for x in gen: print(x) # 0, 1, 2
# Iterate lần 2for x in gen: print(x) # Không in gì! Generator đã exhaustedGenerator không store values
Phần tiêu đề “Generator không store values”# List - Store valueslst = [x for x in range(1000000)] # Chiếm RAM!
# Generator - Generate on-the-flygen = (x for x in range(1000000)) # Không chiếm RAMGiải pháp
Phần tiêu đề “Giải pháp”✅ Solution 1: Convert sang list
Phần tiêu đề “✅ Solution 1: Convert sang list”# Nếu cần dùng nhiều lầngen = (x for x in range(5))data = list(gen) # Convert 1 lần
print(data) # [0, 1, 2, 3, 4]print(data) # [0, 1, 2, 3, 4] ✅✅ Solution 2: Tạo lại generator
Phần tiêu đề “✅ Solution 2: Tạo lại generator”def create_gen(): return (x for x in range(5))
# Dùng lần 1gen1 = create_gen()print(list(gen1)) # [0, 1, 2, 3, 4]
# Dùng lần 2gen2 = create_gen()print(list(gen2)) # [0, 1, 2, 3, 4] ✅✅ Solution 3: itertools.tee
Phần tiêu đề “✅ Solution 3: itertools.tee”import itertools
gen = (x for x in range(5))gen1, gen2 = itertools.tee(gen, 2)
print(list(gen1)) # [0, 1, 2, 3, 4]print(list(gen2)) # [0, 1, 2, 3, 4] ✅Khi nào dùng generator?
Phần tiêu đề “Khi nào dùng generator?”✅ Dùng khi
Phần tiêu đề “✅ Dùng khi”# 1. Data lớndef read_large_file(filename): with open(filename) as f: for line in f: # Generator yield line.strip()
# 2. Infinite sequencesdef fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b
# 3. Pipelinesquares = (x**2 for x in range(1000000))evens = (x for x in squares if x % 2 == 0)Tóm tắt
Phần tiêu đề “Tóm tắt”Generators:
- ✅ Memory efficient
- ⚠️ Chỉ iterate 1 lần
- 🔧 Convert sang list nếu cần reuse
- 🔄 Hoặc tạo lại generator
Pattern:
# Dùng 1 lầngen = (x for x in data)
# Dùng nhiều lầndata_list = list(gen)