Hoppa till huvudinnehåll

Handledning: Python-iteratorer och generatorer

Utforska skillnaden mellan Python-iteratorer och generatorer och lär dig vilka som passar bäst i olika situationer.
Uppdaterad 25 maj 2026  · 10 min läsa

Iteratorer är objekt som kan itereras över. De är en vanlig funktion i programmeringsspråket Python och används ofta för loopar och listkomprehensioner. Alla objekt som kan skapa en iterator kallas för en iterable. 

Det krävs en del arbete för att konstruera en iterator. Till exempel måste implementationen av varje iteratorobjekt bestå av en __iter__()- och en __next__() -metod. Utöver detta måste implementationen också ha ett sätt att spåra objektets interna tillstånd och höja ett undantag av typen StopIteration när inga fler värden kan returneras. Dessa regler kallas iteratorprotokollet

Att implementera en egen iterator är en omständlig process och behövs inte alltid. Ett enklare alternativ är att använda ett generatorobjekt. Generatorer är en speciell typ av funktion som använder nyckelordet yield för att returnera en iterator som kan itereras över, ett värde i taget. 

Förmågan att avgöra när du ska implementera en iterator eller använda en generator förbättrar dina färdigheter som Python-programmerare. I resten av den här handledningen betonar vi skillnaderna mellan dessa två objekt, vilket hjälper dig att välja det bästa för olika situationer. 

Ordlista

Term

Definition

Iterable 

Ett Python-objekt som kan loopas över eller itereras över i en loop. Exempel på iterables är listor, mängder, tupler, ordböcker, strängar osv. 

Iterator

En iterator är ett objekt som kan itereras över. Iteratorer innehåller alltså ett uppräkneligt antal värden. 

Generator

En speciell typ av funktion som inte returnerar ett enskilt värde, utan ett iteratorobjekt med en sekvens av värden.

Lazy evaluation 

En utvärderingsstrategi där vissa objekt bara skapas när de behövs. Därför kallas lazy evaluation ibland också för ”call-by-need”.

Iteratorprotokoll 

En uppsättning regler som måste följas för att definiera en iterator i Python. 

next()

En inbyggd funktion som används för att returnera nästa element i en iterator. 

iter()

En inbyggd funktion som används för att omvandla en iterable till en iterator. 

yield()

Ett Python-nyckelord liknande return, förutom att yield returnerar ett generatorobjekt i stället för ett värde. 

Python-iteratorer och -iterables

Iterables är objekt som kan lämna ifrån sig sina medlemmar en i taget – de kan itereras över. Populära inbyggda Python-datastrukturer som listor, tupler och mängder är iterables. Andra datastrukturer som strängar och ordböcker räknas också som iterables: en sträng kan itereras tecken för tecken, och nycklarna i en ordbok kan itereras över. Som tumregel: betrakta alla objekt som kan användas i en for-loop som en iterable. 

Utforska Python-iterables med exempel

Givet definitionerna kan vi dra slutsatsen att alla iteratorer också är iterables. Men varje iterable är inte nödvändigtvis en iterator. En iterable producerar en iterator först när den faktiskt itereras.

För att demonstrera detta skapar vi en lista, som är en iterable, och tar fram en iterator genom att anropa den inbyggda funktionen iter() på listan. 

list_instance = [1, 2, 3, 4]
print(iter(list_instance))

"""
<list_iterator object at 0x7fd946309e90>
"""

Även om listan i sig inte är en iterator omvandlar anropet till iter() den till en iterator och returnerar iteratorobjektet.

För att visa att inte alla iterables är iteratorer instansierar vi samma listobjekt och försöker anropa funktionen next(), som används för att returnera nästa element i en iterator.  

list_instance = [1, 2, 3, 4]
print(next(list_instance))
"""
--------------------------------------------------------------------
TypeError                         Traceback (most recent call last)
<ipython-input-2-0cb076ed2d65> in <module>()
    3 print(iter(list_instance))
    4
----> 5 print(next(list_instance))
TypeError: 'list' object is not an iterator
"""

I koden ovan ser du att ett försök att anropa next() på listan orsakade ett TypeError – läs mer om undantag och felhantering i Python. Detta beror helt enkelt på att ett listobjekt är en iterable och inte en iterator. 

Utforska Python-iteratorer med exempel

Om målet alltså är att iterera över en lista måste ett iteratorobjekt först skapas. Först därefter kan vi styra iterationen genom listans värden.

# instantiate a list object
list_instance = [1, 2, 3, 4]

# convert the list to an iterator
iterator = iter(list_instance)

# return items one at a time
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))
"""
1
2
3
4
"""

Python skapar automatiskt ett iteratorobjekt när du försöker loopa genom ett iterable-objekt. 

# instantiate a list object
list_instance = [1, 2, 3, 4]

# loop through the list
for item in list_instance:
  print(item)
"""
1
2
3
4
"""

När undantaget StopIteration fångas upp avslutas loopen.

Värdena från en iterator kan bara hämtas från vänster till höger. Python har ingen funktion previous() som låter utvecklare gå baklänges genom en iterator. 

Iteratorers ”lata” natur

Det är möjligt att definiera flera iteratorer baserade på samma iterable-objekt. Varje iterator behåller sitt eget framstegstillstånd. Genom att skapa flera iteratorinstanser av en och samma iterable kan du alltså iterera till slutet i en instans medan en annan fortfarande står i början.

list_instance = [1, 2, 3, 4]
iterator_a = iter(list_instance)
iterator_b = iter(list_instance)
print(f"A: {next(iterator_a)}")
print(f"A: {next(iterator_a)}")
print(f"A: {next(iterator_a)}")
print(f"A: {next(iterator_a)}")
print(f"B: {next(iterator_b)}")
"""
A: 1
A: 2
A: 3
A: 4
B: 1
"""

Observera att iterator_b skriver ut seriens första element.

Vi kan alltså säga att iteratorer har en lat natur: när en iterator skapas levereras inte elementen förrän de begärs. Med andra ord returneras elementen i vår listinstans först när vi uttryckligen ber om dem med next(iter(list_instance))

Alla värden från en iterator kan dock hämtas på en gång genom att anropa en inbyggd container för iterables (t.ex. list(), set(), tuple()) på iteratorobjektet för att tvinga fram att alla element genereras direkt.

# instantiate iterable
list_instance = [1, 2, 3, 4]

# produce an iterator from an iterable
iterator = iter(list_instance)
print(list(iterator))
"""
[1, 2, 3, 4]
"""

Detta rekommenderas inte för stora iteratorer eftersom det tvingar fram att varje element genereras och hålls i minnet på en gång, vilket motverkar syftet med lazy evaluation.

När en datamängd är för stor för att rymmas bekvämt i minnet, eller när du vill ha lat iteration utan att skriva en hel iterator-klass, är en generator oftast ett bättre val.

Python-generatorer

Det snabbaste alternativet till att implementera en iterator är att använda en generator. Även om generatorer kan se ut som vanliga Python-funktioner är de annorlunda. Till att börja med returnerar ett generatorobjekt inte färdiga element. I stället använder det nyckelordet yield för att generera element i farten. Vi kan alltså säga att en generator är en särskild sorts funktion som utnyttjar lazy evaluation.

Generatorer lagrar inte sitt innehåll i minnet, till skillnad från vad du kan förvänta dig av en typisk iterable. Om målet till exempel vore att hitta alla faktorer för ett positivt heltal skulle vi vanligtvis implementera en traditionell funktion (lär dig mer om Python-funktioner i denna handledning) så här:  

def factors(n):
  factor_list = []
  for val in range(1, n+1):
      if n % val == 0:
          factor_list.append(val)
  return factor_list

print(factors(20))
"""
[1, 2, 4, 5, 10, 20]
"""

Koden ovan returnerar hela listan med faktorer. Notera dock skillnaden när en generator används i stället för en traditionell Python-funktion:

def factors(n):
  for val in range(1, n+1):
      if n % val == 0:
          yield val
print(factors(20))

"""
<generator object factors at 0x7fd938271350>
"""

Eftersom vi använde nyckelordet yield i stället för return avslutas inte funktionen efter körningen. I praktiken bad vi Python att skapa ett generatorobjekt i stället för en traditionell funktion, vilket gör att generatorns tillstånd kan spåras. 

Följaktligen är det möjligt att anropa funktionen next() på den ”lata” iteratorn för att visa seriens element ett i taget. 

def factors(n):
  for val in range(1, n+1):
      if n % val == 0:
          yield val
         
factors_of_20 = factors(20)
print(next(factors_of_20))

"""
1
"""

Ett annat sätt att skapa en generator är med en generatoruttryck. Generatoruttryck använder en liknande syntax som en listkomprehension, förutom att de använder parenteser i stället för hakparenteser.

factor_gen = (val for val in range(1, 21) if 20 % val == 0)
print(list(factor_gen))
"""
[1, 2, 4, 5, 10, 20]
"""

Utforska Pythons nyckelord yield

Nyckelordet yield styr flödet i en generatorfunktion. I stället för att lämna funktionen som när return används, returnerar yield kontrollen men kommer ihåg tillståndet för lokala variabler.

Generatorn som returneras från anropet till yield kan tilldelas en variabel och itereras med funktionen next() – detta kör funktionen fram till det första yield-nyckelordet den möter. När yield nås pausas exekveringen av funktionen. När detta sker sparas funktionens tillstånd. Därmed kan vi återuppta exekveringen när vi vill. 

Funktionen fortsätter från anropet till yield. Till exempel: 

def yield_multiple_statements():
  yield "This is the first statement"
  yield "This is the second statement"  
  yield "This is the third statement"
  yield "This is the last statement. Don't call next again!"
example = yield_multiple_statements()
print(next(example))
print(next(example))
print(next(example))
print(next(example))
print(next(example))
"""
This is the first statement
This is the second statement
This is the third statement
This is the last statement. Don't call next again or else!
--------------------------------------------------------------------
StopIteration                  Traceback (most recent call last)
<ipython-input-25-4aaf9c871f91> in <module>()
    11 print(next(example))
    12 print(next(example))
---> 13 print(next(example))
StopIteration:
"""

I koden ovan har vår generator fyra yield-anrop, men vi försöker anropa next fem gånger, vilket resulterar i ett undantag StopIteration. Detta händer eftersom vår generator inte är en oändlig serie, så att anropa den fler gånger än väntat tömde generatorn.

Sammanfattning 

Sammanfattningsvis är iteratorer objekt som kan itereras över, och generatorer är speciella funktioner som utnyttjar lazy evaluation. Om du implementerar en egen iterator måste du skapa metoderna __iter__() och __next__(), medan en generator kan implementeras med nyckelordet yield i en Python-funktion eller ett generatoruttryck. 

Du kan föredra en anpassad iterator framför en generator när du behöver ett objekt med komplext tillståndsbeteende eller om du vill exponera andra metoder utöver __next__(), __iter__() och __init__(). Å andra sidan kan en generator vara att föredra när du arbetar med stora datamängder, eftersom de inte lagrar sitt innehåll i minnet, eller när det inte är nödvändigt att implementera en iterator. 

FAQS

Vad är skillnaden mellan en iterator och en generator i Python?

En iterator är ett objekt som implementerar __iter__() och __next__(). En generator är ett enklare sätt att skapa en iterator med en funktion som använder nyckelordet yield. Alla generatorer är iteratorer, men alla iteratorer är inte generatorer.

När ska jag använda en generator i stället för en lista i Python?

Använd en generator för stora eller oändliga sekvenser, eller när minneseffektivitet är viktig. Listor håller alla element i minnet på en gång, medan generatorer producerar ett värde i taget. För små datamängder som du kommer att återanvända räcker en lista oftast bra.

Vad gör nyckelordet yield i Python?

Nyckelordet yield gör en funktion till en generator. I stället för att returnera och avsluta pausar yield funktionen, returnerar ett värde och kommer ihåg sitt tillstånd så att exekveringen kan återupptas vid nästa anrop.

Hur skapar man en generator i Python?

Antingen skriver du en funktion som använder yield i stället för return, eller så använder du ett generatoruttryck — samma syntax som en listkomprehension men med parenteser, till exempel (x * 2 for x in range(10)).

Är generatorer snabbare än iteratorer i Python?

Inte vad gäller ren hastighet, men de är mer minneseffektiva eftersom de producerar värden vid behov. För stora datamängder innebär det ofta bättre totalprestanda; för små är skillnaden försumbar.

Ämnen

Toppkurser i Python

course

Intermediate Python

4 timmar
1.4M
Level up your data science skills by creating visualizations using Matplotlib and manipulating DataFrames with pandas.
Se detaljerRight Arrow
Starta kursen
Se merRight Arrow