Iterable in Python (Iterable in Python), lesson, Seite 724579
https://www.purl.org/stefan_ram/pub/iter_python (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
Python-Kurs

Iterable in Python 

Nach dem Start einer Python -Implementation gibt es nur wenige Iteratoren.

Trotzdem sind Iteratoren nützlich und spielen eine wichtige Rolle.

Der übliche Weg zu Beschaffung eines Iterators besteht darin, ein anderes Objekt zu nutzen, das einen Iterator liefern kann.

Solche Iteratorlieferanten  werden Iterable  genannt. – „Iterable“ kann auch als Adjektiv verwendet werden: Ein Iterables ist ein iterables Objekt.

Wird die Funktion »iter« mit einem Iterablen als Argument aufgerufen, so ergibt sich ein Iterator, von dem dann mit »next« weitere Objekte erhalten werden können.

Um Objekte von einem Iterablen zu erhalten, wird einem ›iter‹ verwendet und danach wiederholt ›next‹.

Abbildung (mit den englischen Wörtern “iterable ” und “iterator ”)

iter next

iterable --------------------> iterator --------------------> Objekt

Wie bei einem Iterator stellen wir uns auch bei einem Iterablen vor, daß es die Objekte „enthält“, die durch wiederholte Aufrufe von »next« auf seinem Iterator erhalten werden können. (Diese Objekte müssen aber nicht wirklich alle in dem Iterablen gespeichert sein, es kann auch sein, daß sie erst bei Bedarf erzeugt werden.)

Wenn wir sagen, daß ein Iterables Objekte liefere, so meinen wir damit, daß ein vom Iterablen erzeugter Iterator  jene Objekte liefert.

Iterable Zeichenfolgen

str-Zeichenfolgen sind iterabel.

»iter( "ab" )« ist ein Iterator, der jeweils ein Zeichen von »ab« liefert. – Der erste Aufruf von »next« auf diesem Iterator ergibt also das erste Zeichen der str-Zeichenfolge.

Mit „ein Aufruf einer Funktion auf einem Objekt“ ist im voranstehendem Satz der Aufruf der Funktion mit diesem Objekt als Argumentwert gemeint.

Konsolenprotokoll
next( "ab" )
TypeError: 'str' object is not an iterator
Konsolenprotokoll
next( iter( "ab" ))
'a'
Konsolenprotokoll

iterable = "ab"

iterator = iter( iterable )

object = next( iterator )

print( object )

'a'

object = next( iterator )

print( object )

'b'
object = next( iterator )
StopIteration

iterator = iter( iterable )

object = next( iterator )

print( object )

'a'

object = next( iterator )

print( object )

'b'
object = next( iterator )
StopIteration

Mit ›next‹ wird ein weiteres Objekt beantragt, aber der Antrag kann mit ›StopIterationabgelehnt  werden.

Abbildung

iter next
"ab" --------------------> Iterator -------.------------> "a"
|
'------------> "b"
|
StopIteration

iter next
"ab" --------------------> Iterator -------.------------> "a"
|
'------------> "b"
|
StopIteration

Im Gegensatz zu Iteratoren erlauben Iterable also mehrfaches Durchlaufen, indem mit ›iter‹ ein neuer Iterator angefordert wird.

Eine leere  str-Zeichenfolge hat allerdings kein  erstes Zeichen.

Konsolenprotokoll
next( iter( "" ))
StopIteration

Wir sagen kurz: „Das Iterable ›"ab"‹ liefert die beiden Objekte ›"a"‹ und ›"b"‹.“, obwohl wir eigentlich sagen müßten „Der vom Iterable ›"ab"‹ gelieferte Iterator  liefert uns die beiden Objekte ›"a"‹ und ›"b"‹.“

»next« als Wirkwertfunktion

Die Wertfunktion »next« bewirkt auch eine Änderung. Das Argumentobjekt wird auf die nächste Position weitergestellt, also verändert.

Unten ist der Wert aller Vorkommen von »_« das gleiche Objekt, nämlich das Ergebnis des Aufrufs »iter( "ab" )«. Die Werte der Aufrufe »next( _ )« sind jedoch jeweils unterschiedlich, da der Zustand  des Objekts »_« jedesmal ein anderer ist, weil er vom vorigen Aufruf »next( _ )« verändert  wurde.

Konsolenprotokoll
iter( "ab" )
<str_iterator object …>
print( next( _ ))
'a'
print( next( _ ))
'b'
print( next( _ ))
StopIteration
print( next( _ ))
StopIteration

Iterable Listen

Listen sind ebenfalls iterabel.

Eine Liste ergibt sich beispielsweise beim Aufruf von »dir«.

Konsolenprotokoll
dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
next( dir() )
TypeError: 'list' object is not an iterator
next( iter( dir() ))
'__annotations__'
Konsolenprotokoll
iter( dir() )
<list_iterator object …>
print( next( _ ))
__annotations__
print( next( _ ))
__builtins__
print( next( _ ))
__doc__
print( next( _ ))
__loader__
print( next( _ ))
__name__
print( next( _ ))
__package__
print( next( _ ))
__spec__
print( next( _ ))
StopIteration
print( next( _ ))
StopIteration

Iterable Tupel

Auch Tupel sind iterabel.

Iterable Iteratoren

Alle Iteratoren sind „pro forma“ auch Iterable, insofern ›iter‹ mit ihnen aufgerufen werden kann, doch liefern sie dann nur wieder sich selbst als Iterator.

Konsolenprotokoll

from multiprocessing.pool import job_counter

next( job_counter )

0
next( job_counter )
1
next( job_counter )
2

x = iter( job_counter )

x is job_counter

True
next( x )
3
next( job_counter )
4
next( x )
5
next( job_counter )
6

Iterable erkennen

Um zu erkennen, ob etwas iterabel ist, kann in der Dokumentation nachgelesen werden.

Es ist auch möglich, versuchsweise ›iter‹ damit aufzurufen. Es ist dann iterabel, wenn sich keine Fehlermeldung, sondern ein Objekt  ergibt. Jedoch könnte solch ein Aufruf auch unerwünschte Folgen haben, so daß es etwas riskant ist, es einfach auszuprobieren.

Konsole
iter( 2 )
TypeError: 'int' object is not iterable
iter( 'ab' )
<str_iterator object at 0x000000000248EDD0>

enumerate

enumerate‹ ergibt für ein Iterables einen Iterator, der jeweils Paare liefert, die vor dem Objekt noch eine laufende Nummer enthalten. So lassen sich Objekte numerieren.

Konsolenprotokoll

e = enumerate( "elf" )

next( e )

(0, 'e')
next( e )
(1, 'l')
next( e )
(2, 'f')
next( e )
StopIteration
next( e )
StopIteration

Warum Iterable, reichen nicht Iteratoren?

Ein Iterator kann nur einmal durchlaufen werden und ist danach meist für immer erschöpft.

Konsolenprotokoll

e = enumerate( "elf" )

next( e )

(0, 'e')
next( e )
(1, 'l')
next( e )
(2, 'f')
next( e )
StopIteration
next( e )
StopIteration

Von einem Iterablen kann mit »iter« immer wieder ein neuer Iterator für dasselbe Objekt abgeholt werden. Solche ein neuer Iterator beginnt jeweils immer wieder am Anfang. So ist es auf eine einheitliche Weise möglich, ein Objekt mehrfach  zu durchlaufen.

(Im obigen Beispiel könnte zwar erneut »enumerate« aufgerufen werden, aber dies ist nicht auf andere Iteratoren übertragbar. Bei Iterablen kann stehts für alle Iterablen in einheitlicher Weise »iter« verwendet werden, um einen neuen Interator zu erhalten.)

Konsolenprotokoll
iter( "ab" )
<str_iterator object …>
print( next( _ ))
'a'
print( next( _ ))
'b'
iter( "ab" )
<str_iterator object …>
print( next( _ ))
'a'
print( next( _ ))
'b'

Die natürlichen Zahlen als Iterables

Da es unendlich viele  natürliche Zahlen gibt, können sie nicht alle im Computer abgespeichert werden. Es ist jedoch möglich, ein Iterables zu erzeugen, daß alle natürlichen Zahlen liefert, da sie dazu nicht alle gleichzeitig abgespeichert werden müssen.

Das Iterable »count()« liefert alle natürlichen Zahlen  (beginnend mit Null).

Konsolenprotokoll (mit den englischen Wörtern “iterable ” und “iterator ”)

from itertools import count

iterable = count()

iterator = iter( count() )

print( next( iterator ))

0
print( next( iterator ))
1
print( next( iterator ))
2

Iterable manifestieren

Iterable können Iteratoren liefern und so als Quellen für Objekte dienen. Es könnte aber sein, daß diese Objekte erst beim Aufruf von ›next‹ erzeugt werden.

Im Gegensatz dazu sind die in einem Tupel enthaltenen Objekte alle schon im Speicher vorhanden.

Daher könnte es sein, daß ein Iterables, daß Milliarden von Objekten liefert, nur wenig Speicherplatz benötigt. Ein Tupel mit Milliarden von Objekten würde aber relativ viel Speicherplatz kosten.

Wenn ›tuple‹ mit einem Iterablen als Argument aufgerufen wird, so wird ein Tupel im Speicher erzeugt, daß alle vom Iterablen gelieferten Objekte enthält. Dazu wird aus dem Iterablen zunächst mit ›iter‹ ein Iterator erzeugt, und von dem werden dann alle Objekte abgerufen bis ›StopIteration‹ erscheint und im Tupel gespeichert.

Konsolenprotokoll

iterable = "ab"

tuple( iterable )

('a', 'b')

Wir sagen dazu auch, daß das Iterable als Tupel manifestiert  wurde – das heißt, daß das Tupel nun alle Werte des Iterablen so enthält, daß diese jeweils im Tupel abgespeichert wurden.

⚠ Warnung Ein Versuch, »tuple( count() )« auszuwerten, könnte Computer vorübergehend (bis zu einem Neustart) unbrauchbar machen und dadurch zu Datenverlust führen. Daher sollte dies vermieden werden! 

Bei der Auswertung von »tuple( count() )« könnte versucht werden, alle Zahlen von ›count()‹ abzurufen und abzuspeichern, dadurch könnte so viel Speicher belegt werden, daß der Computer keinen Speicherplatz für wichtige Systemoperationen mehr hat.

Jeder Iterator ist iterabel 

Zumindest formal ist jeder Iterator auch iterabel, doch ergibt der Aufruf von »iter« auf einem Iterator wieder den Iterator selber, ohne daß er auf diese Weise zurückgesetzt wird. Trotzdem ist dies hilfreich, weil auf diese Weise jeder Iterator dort eingesetzt werden kann, wo ein Iterables erwartet wird.

Konsolenprotokoll

i = iter( "ab" )

tuple( i )

('a', 'b')
Zitat *
Iterator objects also need to implement this method; they are required to return themselves.
The Python Language Reference, Release 3.9.0a3, 3.3.7 Emulating container types

Motivation

Oft findet man in der Python -Dokumentation die Aussage, daß bestimmte Objekte iterabel sein sollen.

In dem folgenden Zitat wird beispielweise gesagt, daß das Argument von ›all‹ iterabel sein muß.

Zitat
all(iterable)
Return True if all elements of the iterable are true (or if the iterable is empty).
The Python Library Reference, Release 3.9.0a3

Anwendungsgebiete von Iterablen

Übersicht Iterable  und Funktoren 

Iteratoren

from multiprocessing.pool import job_counter
job_counter

from sys import stdin
stdin

Ergebnisse von »enumerate«
Ergebnisse von »iter«
Iterable
from itertools import count
count()
alle Iteratoren  (formal)
str-Objekte
list-Objekte
tuple-Objekte
Funktoren, die Iteratoren akzeptieren

next

iter

Funktoren, die Iterable akzeptieren
iter

Übungsfragen

?   Übungsfrage 0

Welche Ausgabe ergibt die folgende Anweisungsfolge?

Anweisungen (mit den englischen Wörtern “iterable ” und “iterator ”)
iterable = 'abc'
iterator = iter( iterable )
print( next( iterator )+ next( iterator ))

?   Übungsfrage 1

Welche Ausgabe ergibt die folgende Anweisungsfolge?

Anweisungen
G = 'def'
Q = iter( G )
R = iter( G )
print( next( Q )+ next( R ))

?   Übungsfrage 2 ⃗

Welche Ausgabe ergibt die folgende Anweisungsfolge?

Anweisungen (mit den englischen Wörtern “iterable ” und “iterator ”)

Text = ''

iterable = 'abc'
iterator = iter( iterable )
Text = next( iterator )+ Text
Text = next( iterator )+ Text
Text = next( iterator )+ Text

print( Text )

?   Übungsfrage 3 ⃗

Welche Ausgabe ergibt die folgende Anweisungsfolge?

Anweisungen (mit den englischen Wörtern “iterable ” und “iterator ”)

Text = ''

iterable = 'abc'
iterator = iter( iterable )
Text = next( iterator )+ Text
Text = next( iterator )+ Text

iterator = iter( iterable )
Text = next( iterator )+ Text
Text = next( iterator )+ Text

print( Text )

?   Übungsfrage ⃗

Können Sie den Wert der Auswertung von »next( iter( next( iter( dir() ))))« vorhersagen?

Konsolenprotokoll
dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
next( iter( next( iter( dir() ))))
?

„Iterables“

Iterables

woertliche Bedeutung: Ein Objekt, (ueber) das iteriert werden kann

Wortklasse: Nomen
Artikel: das
Flexionsklasse: Adjektivisch

Starke Flexion (ohne Artikel)

Singular Plural
Neutrum Neutrum
Artikel Nomen Artikel Nomen

Nominativ - Iterables - Iterable
Akkusativ - Iterables - Iterable
Dativ - Iterablem - Iterablen
Genitiv - Iterablen - Iterabler

Schwache Flexion (mit bestimmtem Artikel)

Singular Plural
Neutrum Neutrum
Artikel Nomen Artikel Nomen

Nominativ das Iterable die Iterablen
Akkusativ das Iterable die Iterablen
Dativ dem Iterablen den Iterablen
Genitiv des Iterablen der Iterablen

Gemischte Flexion (mit ein, kein, Possessivpronomen u.a.)

Singular Plural
Neutrum Neutrum
Artikel Nomen Artikel Nomen

Nominativ ein Iterables keine Iterablen
Akkusativ ein Iterables keine Iterablen
Dativ einem Iterablen keinen Iterablen
Genitiv eines Iterablen keiner Iterablen

 

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram724579 stefan_ram:724579 Iterable in Python Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd724579, slrprddef724579, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/iter_python