Giv efter Python tutorial: Generator & Yield vs Return Eksempel

Hvad er Python udbytte?

Udbytte sรธgeordet i python fungerer som et afkast med den eneste

forskellen er, at i stedet for at returnere en vรฆrdi, giver den et generatorobjekt tilbage til den, der ringer.

Nรฅr en funktion kaldes, og udfรธrelsestrรฅden finder et yield-nรธgleord i funktionen, stopper funktionsudfรธrelsen ved selve den linje, og den returnerer et generatorobjekt tilbage til den, der ringer.

Syntaks

yield expression

Beskrivelse

Python yield returnerer et generatorobjekt. Generators er specielle funktioner, der skal gentages for at fรฅ vรฆrdierne.

Nรธgleordet yield konverterer udtrykket givet til en generatorfunktion, der giver et generatorobjekt tilbage. For at fรฅ vรฆrdierne af objektet, skal det gentages for at aflรฆse vรฆrdierne givet til udbyttet.

Eksempel: Udbyttemetode

Her er et simpelt eksempel pรฅ yield. Funktionen testyield() har et yield-nรธgleord med strengen "Velkommen til Guru99 Python Vejledningerโ€œ. Nรฅr funktionen kaldes, udskrives output, og det giver et generatorobjekt i stedet for den faktiske vรฆrdi.

def testyield():
  yield "Welcome to Guru99 Python Tutorials"
output = testyield()
print(output)

Output:

<generator object testyield at 0x00000028265EB9A8>

Det givne output er et generatorobjekt, som har den vรฆrdi, vi har givet for at give.

Men vi fรฅr ikke den besked, vi skal give for at give efter i output!

For at udskrive meddelelsen givet til udbytte skal generatorobjektet gentages som vist i eksemplet nedenfor:

def testyield():
  yield "Welcome to Guru99 Python Tutorials"

output = testyield()
for i in output:
    print(i)

Output:

Welcome to Guru99 Python Tutorials

Hvad er Generatorsi Python?

Generators er funktioner, der returnerer et iterabelt generatorobjekt. Vรฆrdierne fra generatorobjektet hentes en ad gangen i stedet for den fulde liste sammen, og for at fรฅ de faktiske vรฆrdier kan du derfor bruge en for-loop ved at bruge next() eller list() metoden.

Ved brug af Generator funktion

Du kan oprette generatorer ved hjรฆlp af generatorfunktion og ved hjรฆlp af generatorudtryk.

En generatorfunktion er som en normal funktion, i stedet for at have en returvรฆrdi vil den have et udbytte-nรธgleord.

For at oprette en generatorfunktion skal du tilfรธje et nรธgleord for udbytte. De fรธlgende eksempler viser, hvordan man opretter en generatorfunktion.

def generator():
    yield "H"
    yield "E"
    yield "L"
    yield "L"
    yield "O"

test = generator()
for i in test:
    print(i)

Output:

H
E
L
L
O

Forskellen mellem normal funktion v/s Generator funktion.

Lad os forstรฅ, hvordan en generatorfunktion er forskellig fra en normal funktion.

Der er 2 funktioner normal_test() og generator_test().

Begge funktioner formodes at returnere strengen "Hello World". Normal_test() bruger return og generator_test() bruger udbytte.

# Normal function
def normal_test():
    return "Hello World"
	
#Generator function
def generator_test():
	yield "Hello World"
print(normal_test()) #call to normal function
print(generator_test()) # call to generator function

Output:

Hello World
<generator object generator_test at 0x00000012F2F5BA20>

Outputtet viser, at nรฅr du kalder den normale funktion normal_test() returnerer den Hello World-streng. For en generatorfunktion med nรธgleordet udbytte vender den tilbage og ikke strengen.

Dette er hovedforskellen mellem en generatorfunktion og en normal funktion. For nu at fรฅ vรฆrdien fra generatorobjektet skal vi enten bruge objektet inde for loop eller bruge next() metoden eller gรธre brug af list().

print(next(generator_test()))  # will output Hello World

Endnu en forskel at tilfรธje til normal funktion v/s generatorfunktion er, at nรฅr du kalder en normal funktion, vil udfรธrelsen starte og stoppe, nรฅr den nรฅr afkast og vรฆrdien returneres til den, der ringer. Sรฅ nรฅr eksekveringen starter, kan du ikke stoppe den normale funktion ind imellem, og den stopper fรธrst, nรฅr den stรธder pรฅ et returnerende sรธgeord.

Men i tilfรฆlde af generatorfunktion, nรฅr udfรธrelsen starter, nรฅr den fรฅr det fรธrste udbytte, stopper den udfรธrelsen og giver generatorobjektet tilbage. Du kan bruge generatorobjektet til at fรฅ vรฆrdierne og ogsรฅ pause og genoptage tilbage i henhold til dit krav.

Hvordan aflรฆses vรฆrdierne fra generatoren?

Du kan lรฆse vรฆrdierne fra et generatorobjekt ved hjรฆlp af en list(), for-loop og nรฆste() metode.

Brug af: list()

En liste er et iterabelt objekt, der har sine elementer inden for parentes. Brug af list() pรฅ et generatorobjekt vil give alle de vรฆrdier, som generatoren har.

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
print(list(num))

Output:

[0, 2, 4, 6, 8]

Bruger: for-in

I eksemplet er der en funktion defineret lige_numre(), som vil give dig alle lige tal for de n definerede. Kaldet til funktionen even_numbers() vil returnere et generatorobjekt, som bruges inde i for-loop.

Eksempel:

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
for i in num:
    print(i)

Output:

0
2
4
6
8

Brug af next()

Next()-metoden giver dig det nรฆste element i listen, arrayet eller objektet. Nรฅr listen er tom, og hvis next() kaldes, vil den give en fejl tilbage med stopIteration-signal. Denne fejl fra next() indikerer, at der ikke er flere elementer pรฅ listen.

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))

Output:

0
2
4
6
8
Traceback (most recent call last):
  File "main.py", line 11, in <module>
    print(next(num))
StopIteration

Generators er engangsbrug

I tilfรฆlde af generatorer er de kun tilgรฆngelige til brug รฉn gang. Hvis du prรธver at bruge dem igen, vil den vรฆre tom.

For eksempel:

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
for i in num:
    print(i)

print("\n")
print("Calling the generator again: ", list(num))

Output:

0
2
4
6
8
Calling the generator again:  []

Hvis du รธnsker, at outputtet skal bruges igen, bliver du nรธdt til at foretage opkaldet for at fungere igen.

Eksempel: Generators og udbytte for Fibonacci-serien

Fรธlgende eksempel viser, hvordan man bruger generatorer og udbytte i Python. Eksemplet vil generere Fibonacci-serien.

def getFibonnaciSeries(num):
    c1, c2 = 0, 1
    count = 0
    while count < num:
        yield c1
        c3 = c1 + c2
        c1 = c2
        c2 = c3
        count += 1
fin = getFibonnaciSeries(7)
print(fin)
for i in fin:
    print(i)

Output:

<generator object getFibonnaciSeries at 0x0000007F39C8BA20>
0
1
1
2
3
5
8

Eksempel: Opkaldsfunktion med Yield

I dette eksempel vil se, hvordan man kalder en funktion med udbytte.

Nedenstรฅende eksempel har en funktion kaldet test(), der returnerer kvadratet af det givne tal. Der er en anden funktion kaldet getSquare() der bruger test() med yield nรธgleord. Outputtet giver kvadratvรฆrdien for et givet talomrรฅde.

def test(n):
    return n*n

def getSquare(n):
    for i in range(n):
        yield test(i)

sq = getSquare(10)
for i in sq:
    print(i)

Output:

0
1
4
9
16
25
36
49
64
81

Hvornรฅr skal du bruge Yield i stedet for Return in Python

Python3 Udbytte nรธgleordet returnerer en generator til den, der ringer, og udfรธrelsen af โ€‹โ€‹koden starter fรธrst, nรฅr generatoren gentages.

A afkast i en funktion er slutningen af โ€‹โ€‹funktionsudfรธrelsen, og en enkelt vรฆrdi gives tilbage til den, der ringer.

Her er situationen, hvor du skal bruge Yield i stedet for Return

  • Brug udbytte i stedet for afkast, nรฅr datastรธrrelsen er stor
  • Yield er det bedste valg, nรฅr du har brug for, at din eksekvering er hurtigere pรฅ store datasรฆt
  • Brug udbytte, nรฅr du vil returnere et stort sรฆt vรฆrdier til den kaldende funktion
  • Yield er en effektiv mรฅde at producere data, der er store eller uendelige.

Udbytte vs. afkast

Her er forskellene mellem udbytte og afkast

Udbytte Returnering
Yield returnerer et generatorobjekt til den, der ringer, og udfรธrelsen af โ€‹โ€‹koden starter fรธrst, nรฅr generatoren itereres. Et retur i en funktion er slutningen af โ€‹โ€‹funktionsudfรธrelsen, og en enkelt vรฆrdi gives tilbage til den, der ringer.
Nรฅr funktionen kaldes, og den stรธder pรฅ nรธgleordet yield, stopper funktionsudfรธrelsen. Det returnerer generatorobjektet tilbage til den, der ringer. Funktionsudfรธrelsen starter fรธrst, nรฅr generatorobjektet udfรธres. Nรฅr funktionen kaldes, starter eksekveringen, og vรฆrdien gives tilbage til den, der ringer, hvis der er returnรธgleord. Returen inde i funktionen markerer slutningen af โ€‹โ€‹funktionsudfรธrelsen.
udbytte udtryk returnere udtryk
Der bruges ingen hukommelse, nรฅr nรธgleordet udbytte bruges. Hukommelsen er allokeret til den returnerede vรฆrdi.
Meget nyttig, hvis du skal hรฅndtere stor datastรธrrelse, da hukommelsen ikke bruges. Praktisk til meget lille datastรธrrelse.
Ydeevnen er bedre, hvis nรธgleordet yield bruges til stor datastรธrrelse. Der bruges meget hukommelse, hvis datastรธrrelsen er enorm, hvilket vil hรฆmme ydeevnen.
Udfรธrelsestiden er hurtigere i tilfรฆlde af udbytte for store datastรธrrelser. Den anvendte udfรธrelsestid er mere, da der er ekstra behandling udfรธrt i tilfรฆlde af, at hvis din datastรธrrelse er enorm, vil den fungere fint for smรฅ datastรธrrelser.

Resumรฉ

  • Nรธgleordet yield i python fungerer som et retur, med den eneste forskel er, at i stedet for at returnere en vรฆrdi, giver det en generatorfunktion tilbage til den, der ringer.
  • En generator er en speciel type iterator, som, nรฅr den er brugt, ikke vil vรฆre tilgรฆngelig igen. Vรฆrdierne gemmes ikke i hukommelsen og er kun tilgรฆngelige, nรฅr de kaldes op.
  • Vรฆrdierne fra generatoren kan lรฆses ved hjรฆlp af for-in, list() og next() metoden.
  • Den stรธrste forskel mellem udbytte og afkast er, at udbytte returnerer en generatorfunktion til den, der ringer, og retur giver en enkelt vรฆrdi til den, der ringer.
  • Yield gemmer ingen af โ€‹โ€‹vรฆrdierne i hukommelsen, og fordelen er, at det er nyttigt, nรฅr datastรธrrelsen er stor, da ingen af โ€‹โ€‹vรฆrdierne er gemt i hukommelsen.
  • Ydeevnen er bedre, hvis nรธgleordet yield bruges i sammenligning med at vende tilbage for store datastรธrrelser.

Opsummer dette indlรฆg med: