Python Generators

பைத்தான் ஜெனரேட்டர்கள் கற்றுக்கொள்ளுங்கள்

Python - ஜெனரேட்டர்கள்

ஜெனரேட்டர்கள் அவற்றின் இயக்கத்தை இடைநிறுத்தி மீண்டும் தொடக்கக்கூடிய செயல்பாடுகள்.

ஜெனரேட்டர்கள் என்றால் என்ன?

இடைநிறுத்தும் திறன்

சிறப்பம்சம்: இயக்கத்தை இடைநிறுத்தி மீண்டும் தொடங்கும்

முக்கியச்சொல்: yield

நன்மை: நினைவக திறமை

மெதுவான மதிப்பீடு

சிறப்பம்சம்: தேவைக்கேற்ப மதிப்புகளை உருவாக்குகிறது

வழிமுறை: Lazy Evaluation

நன்மை: பெரிய தரவுகளுக்கு ஏற்றது

முடிவிலா வரிசைகள்

சிறப்பம்சம்: முடிவில்லாத வரிசைகளை உருவாக்கும்

எடுத்துக்காட்டு: Fibonacci sequence

நன்மை: நினைவகத்தை முழுமையாக பயன்படுத்தாது

ஜெனரேட்டர் செயல்பாடு

ஒரு ஜெனரேட்டர் செயல்பாடு அழைக்கப்படும்போது, அது ஒரு ஜெனரேட்டர் பொருளைத் தரும், இது ஒரு இட்டரேட்டர் ஆகும்.

🏁 உதவிக்குறிப்பு:

செயல்பாட்டிற்குள் உள்ள குறியீடு இன்னும் செயல்படுத்தப்படவில்லை, அது தொகுக்கப்பட்டது மட்டுமே. நீங்கள் ஜெனரேட்டரை மீண்டும் இயக்கும் போது மட்டுமே செயல்பாடு செயல்படுத்தப்படும்.

எடுத்துக்காட்டு

ஒரு எளிய ஜெனரேட்டர் செயல்பாடு:

def my_generator():
    yield 1
    yield 2
    yield 3

for value in my_generator():
    print(value)

இயக்க படிப்படியாக:

படி 1: my_generator() அழைக்கப்படுகிறது → ஜெனரேட்டர் பொருள் திரும்பும்

படி 2: for லூப் next() ஐ அழைக்கிறது

படி 3: முதல் yield 1 சந்திக்கப்படுகிறது → 1 திரும்பும்

படி 4: அடுத்த next() அழைப்பு → yield 2 சந்திக்கப்படுகிறது

படி 5: மூன்றாவது next() அழைப்பு → yield 3 சந்திக்கப்படுகிறது

வெளியீடு: 1, 2, 3 (ஒவ்வொரு வரியிலும்)

yield முக்கியச்சொல்

yield முக்கியச்சொல் ஒரு செயல்பாட்டை ஜெனரேட்டராக ஆக்குகிறது.

🔄 குறிப்பு:

yield சந்திக்கப்படும் போது, செயல்பாட்டின் நிலை சேமிக்கப்பட்டு, மதிப்பு திரும்பும். அடுத்த முறை ஜெனரேட்டர் அழைக்கப்படும் போது, அது விட்ட இடத்திலிருந்து தொடர்கிறது.

எடுத்துக்காட்டு

எண்களை வழங்கும் ஜெனரேட்டர்:

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

for num in count_up_to(5):
    print(num)

yield vs return

return: செயல்பாட்டை முடிக்கிறது

yield: செயல்பாட்டை இடைநிறுத்துகிறது

return: ஒரு முறை மட்டுமே அழைக்க முடியும்

yield: பல முறை அழைக்க முடியும்

நிலை பாதுகாப்பு

உள்ளூர் மாறிகள்: சேமிக்கப்படுகின்றன

நிரல் காட்டி: சேமிக்கப்படுகிறது

அடைப்பு மாறிகள்: சேமிக்கப்படுகின்றன

மறு தொடக்கம்: சரியாக இருக்கும்

நினைவக திறமை

ஜெனரேட்டர்கள் நினைவக-திறமையானவை, ஏனெனில் அவை எல்லாவற்றையும் நினைவகத்தில் சேமிக்காமல் பறக்கும்போது மதிப்புகளை உருவாக்குகின்றன.

எடுத்துக்காட்டு

பெரிய வரிசைகளுக்கான ஜெனரேட்டர்:

def large_sequence(n):
    for i in range(n):
        yield i

# இது நினைவகத்தில் ஒரு மில்லியன் எண்களை உருவாக்காது
gen = large_sequence(1000000)
print(next(gen))  # Output: 0
print(next(gen))  # Output: 1
print(next(gen))  # Output: 2

பட்டியல் அணுகுமுறை

# நினைவகத்தில் பட்டியல் உருவாக்குகிறது
numbers = [i for i in range(1000000)]
# அனைத்து 1 மில்லியன் எண்களும் நினைவகத்தில் உள்ளன
print(numbers[0])  # 0
print(numbers[1])  # 1
print(numbers[2])  # 2

நினைவக பயன்பாடு: அதிகம்

தொடக்கம் வேகம்: மெதுவானது

பயன்பாடு: சிறிய தரவுகள்

ஜெனரேட்டர் அணுகுமுறை

# நினைவகத்தில் பட்டியல் உருவாக்காது
def numbers_gen(n):
    for i in range(n):
        yield i

gen = numbers_gen(1000000)
# ஒரு நேரத்தில் ஒரு எண் மட்டுமே நினைவகத்தில் உள்ளது
print(next(gen))  # 0
print(next(gen))  # 1
print(next(gen))  # 2

நினைவக பயன்பாடு: குறைவு

தொடக்கம் வேகம்: வேகமானது

பயன்பாடு: பெரிய தரவுகள்

next() பயன்படுத்தி ஜெனரேட்டர்கள்

நீங்கள் next() செயல்பாட்டைப் பயன்படுத்தி ஒரு ஜெனரேட்டரை கைமுறையாக மீண்டும் இயக்கலாம்:

எடுத்துக்காட்டு 1: கைமுறை மறு இயக்கம்

def simple_gen():
    yield "Emil"
    yield "Tobias"
    yield "Linus"

gen = simple_gen()
print(next(gen))  # Output: Emil
print(next(gen))  # Output: Tobias
print(next(gen))  # Output: Linus

எடுத்துக்காட்டு 2: StopIteration

def simple_gen():
    yield 1
    yield 2

gen = simple_gen()
print(next(gen))  # Output: 1
print(next(gen))  # Output: 2
# print(next(gen))  # StopIteration error

# பிழையை கையாளுதல்
gen = simple_gen()
try:
    print(next(gen))
    print(next(gen))
    print(next(gen))  # StopIteration
except StopIteration:
    print("Generator exhausted")

ஜெனரேட்டர் வெளிப்பாடுகள்

பட்டியல் காம்ப்ரிஹென்ஷன்களைப் போலவே, சதுர அடைப்புக்குறிகளுக்குப் பதிலாக அடைப்புக்குறிகளைப் பயன்படுத்தி ஜெனரேட்டர் வெளிப்பாடுகளை உருவாக்கலாம்:

பட்டியல் காம்ப்ரிஹென்ஷன்

# பட்டியல் காம்ப்ரிஹென்ஷன் - பட்டியலை உருவாக்குகிறது
list_comp = [x * x for x in range(5)]
print(list_comp)
# Output: [0, 1, 4, 9, 16]
print(type(list_comp))
# Output: <class 'list'>

நினைவகம்: அனைத்து உருப்படிகளும் நினைவகத்தில் உள்ளன

பயன்பாடு: சிறிய தரவுகள்

ஜெனரேட்டர் வெளிப்பாடு

# ஜெனரேட்டர் வெளிப்பாடு - ஜெனரேட்டரை உருவாக்குகிறது
gen_exp = (x * x for x in range(5))
print(gen_exp)
# Output: <generator object <genexpr> at 0x...>
print(type(gen_exp))
# Output: <class 'generator'>
print(list(gen_exp))
# Output: [0, 1, 4, 9, 16]

நினைவகம்: ஒரு நேரத்தில் ஒரு உருப்படி மட்டுமே

பயன்பாடு: பெரிய தரவுகள்

நடைமுறை எடுத்துக்காட்டு

# பட்டியல் இல்லாமல் சதுரங்களின் கூட்டுத்தொகையைக் கணக்கிடுதல்
total = sum(x * x for x in range(10))
print(total)  # Output: 285

# இது பின்வரும் விட சிறந்தது:
# total = sum([x * x for x in range(10)])  # பட்டியலை உருவாக்குகிறது

Fibonacci வரிசை ஜெனரேட்டர்

Fibonacci வரிசையை உருவாக்க ஜெனரேட்டர்களைப் பயன்படுத்தலாம். இது நினைவகம் தீர்ந்துவிடாமல் காலவரையின்றி மதிப்புகளை உருவாக்கத் தொடரும்:

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

# முதல் 10 Fibonacci எண்களைப் பெறவும்
gen = fibonacci()
for i in range(10):
    print(f"Fibonacci({i}): {next(gen)}")

முடிவிலா ஜெனரேட்டர் நன்மைகள்:

நினைவகம்: ஒரு நேரத்தில் 2 எண்கள் மட்டுமே நினைவகத்தில் உள்ளன

நெகிழ்வுத்தன்மை: எத்தனை எண்கள் தேவை என்பதை தீர்மானிக்க முடியும்

நிறுத்துதல்: எந்த நேரத்திலும் நிறுத்தலாம்

மறுதொடக்கம்: புதிய ஜெனரேட்டரை உருவாக்கலாம்

ஜெனரேட்டர் முறைகள்

send() முறை

send() முறை நீங்கள் ஜெனரேட்டருக்கு ஒரு மதிப்பை அனுப்ப அனுமதிக்கிறது:

def echo_generator():
    while True:
        received = yield
        print("Received:", received)

gen = echo_generator()
next(gen)  # ஜெனரேட்டரைத் தொடங்கவும்
gen.send("Hello")   # Received: Hello
gen.send("World")   # Received: World
gen.send("Python")  # Received: Python

close() முறை

close() முறை ஜெனரேட்டரை நிறுத்துகிறது:

def my_gen():
    try:
        yield 1
        yield 2
        yield 3
    finally:
        print("Generator closed")

gen = my_gen()
print(next(gen))  # Output: 1
gen.close()       # Output: Generator closed
# print(next(gen))  # StopIteration error

throw() முறை

throw() முறை ஜெனரேட்டருக்குள் ஒரு விதிவிலக்கை எறிய அனுமதிக்கிறது:

def my_gen():
    try:
        yield 1
        yield 2
    except ValueError:
        print("ValueError caught in generator")

gen = my_gen()
print(next(gen))  # Output: 1
gen.throw(ValueError, "Test error")  # Output: ValueError caught in generator

நிஜ உலக பயன்பாட்டு எடுத்துக்காட்டு

பெரிய கோப்பு செயலாக்கம்

def read_large_file(file_path):
    """பெரிய கோப்பை வரி வரியாகப் படிக்கும் ஜெனரேட்டர்"""
    with open(file_path, 'r') as file:
        for line in file:
            yield line.strip()

# பயன்பாடு:
# for line in read_large_file('huge_file.txt'):
#     process_line(line)

தரவு குழாய்

def number_generator(n):
    for i in range(n):
        yield i

def square_generator(numbers):
    for num in numbers:
        yield num * num

def filter_even(numbers):
    for num in numbers:
        if num % 2 == 0:
            yield num

# ஜெனரேட்டர் குழாய்
pipeline = filter_even(square_generator(number_generator(10)))
print(list(pipeline))  # [0, 4, 16, 36, 64]

பயிற்சி

பின்வரும் குறியீட்டின் வெளியீடு என்னவாக இருக்கும்?

def number_generator():
    yield 10
    yield 20
    yield 30

gen = number_generator()
print(next(gen))
print(next(gen))
result = sum(gen)
print(result)

பயிற்சி கேள்வி:

10, 20, 60
✗ தவறு! sum(gen) மீதமுள்ள உருப்படியை மட்டுமே கூட்டுகிறது (30). ஏற்கனவே 10 மற்றும் 20 பயன்படுத்தப்பட்டன.
10, 20, 30
✓ சரி! முதல் next() 10 ஐத் தரும், இரண்டாவது next() 20 ஐத் தரும். sum(gen) மீதமுள்ள உருப்படியை (30) கூட்டும், ஏனெனில் ஜெனரேட்டர்கள் அவற்றின் நிலையை நினைவில் வைத்திருக்கும்.
10, 20, 0
✗ தவறு! sum(gen) காலி இல்லை. ஜெனரேட்டர் இன்னும் ஒரு உருப்படியை (30) கொண்டுள்ளது, இது sum() மூலம் பயன்படுத்தப்படும்.
Error ஏற்படும்
✗ தவறு! இந்த குறியீட்டில் பிழை இல்லை. அனைத்து செயல்பாடுகளும் செல்லுபடியாகும், ஏனெனில் sum() ஒரு ஜெனரேட்டரை ஏற்கும்.

சிறந்த நடைமுறைகள்

பெரிய தரவுகளுக்கு ஜெனரேட்டர்களைப் பயன்படுத்தவும்: நினைவக திறனுக்காக
காம்ப்ரிஹென்ஷன்களுக்கு ஜெனரேட்டர் வெளிப்பாடுகளைப் பயன்படுத்தவும்: (x for x in iterable)
தரவு குழாய்களுக்கு ஜெனரேட்டர்களைப் பயன்படுத்தவும்: பல உருமாற்றங்களை இணைக்க
ஒரு ஜெனரேட்டரை ஒரு முறைக்கு மேல் மீண்டும் இயக்க வேண்டாம்: அவை தீர்ந்துவிட்டால், மீண்டும் உருவாக்கவும்
முடிவிலா வரிசைகளுக்கு ஜெனரேட்டர்களைப் பயன்படுத்தவும்: Fibonacci போன்றவை
கோப்பு செயலாக்கத்திற்கு ஜெனரேட்டர்களைப் பயன்படுத்தவும்: ஒரு நேரத்தில் ஒரு வரி