مولدها در پایتون

yield، تفاوت با لیست، مصرف بهینه حافظه و کاربردهای generator

مولد (Generator) چیست؟

مولد نوع خاصی از تابع است که به‌جای برگرداندن یک مقدار، دنباله‌ای از مقادیر را تولید می‌کند — یکی‌یکی و با مصرف بهینه حافظه.

yield

به‌جای return از yield استفاده می‌کنیم:

def count_up_to(n):
    i = 1
    while i <= n:
        yield i
        i += 1

# استفاده
for num in count_up_to(5):
    print(num)
# 1, 2, 3, 4, 5

تفاوت yield و return

returnyield
تابع را تمام می‌کندتابع را متوقف و بعداً ادامه می‌دهد
یک مقدارچند مقدار (یکی‌یکی)
حافظه ثابتحافظه بهینه

مزیت اصلی: حافظه

# لیست — همه در حافظه
numbers = [x ** 2 for x in range(1000000)]  # ~۸ مگابایت!

# مولد — یکی‌یکی تولید می‌شود
numbers = (x ** 2 for x in range(1000000))  # ~۱۰۰ بایت!

دسترسی به مقادیر

gen = count_up_to(3)

print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3
# print(next(gen))  # StopIteration!

مولد فیبوناچی بی‌نهایت

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

# ۱۰ عدد اول
fib = fibonacci()
for _ in range(10):
    print(next(fib))
# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

Generator Expression

مثل list comprehension اما با پرانتز:

# لیست (همه در حافظه)
squares_list = [x ** 2 for x in range(5)]

# مولد (یکی‌یکی)
squares_gen = (x ** 2 for x in range(5))

print(list(squares_gen))  # [0, 1, 4, 9, 16]

مثال: خواندن فایل بزرگ

def read_large_file(filename):
    with open(filename) as f:
        for line in f:
            yield line.strip()

خلاصه

مفهومتوضیح
yieldتولید مقدار و توقف
next(gen)مقدار بعدی
(expr)generator expression
مزیتحافظه بهینه

این مبحث بخشی از دوره آموزش کامل پایتون است.

ابزارهای مرتبط