Sequenzen in Python
Neben Attributen kann ein Objekt auch Einträge enthalten.
Die Bedeutung bestimmter Attribute ist bereits durch die Sprache Python oder durch ihre Standardbibliothek festgelegt. Für Einträge eines Objektes kann ein Programm hingegen in der Regel willkürliche Festlegungen treffen – es gibt keine Namen, die schon durch Python oder den Typ des Objekts festgelegt wurden. Daher bieten Einträge mehr Freiheit bei ihrer Festlegung.
Jeder Eintrag hat eine bestimmte Positionsnummer. Die erste Positionsnummer ist «0».
Bei Zeichenfolgen sind die Einträge die einzelnen Zeichen.
- Protokoll
from operator import getitem
getitem( 'abc', 0 )
'a'
getitem( 'abc', 3 )
IndexError: string index out of range
getitem( 'abc', 2 )
'c'
getitem( 'abc', 1 )
'b'
Die Funktion ›len‹ ergibt die Anzahl der Einträge.
- Protokoll
len( 'abc' )
3
Das Sequenz-Protokoll Man sagt von Objekte, die »len« und »getitem« mit Zahlen ab «0» unterstützen, daß sie das Sequenz-Protokoll unterstützen (implementieren) und nennt solche Objekte Sequenzen.
str-Objekte unterstützen das Sequenzprotokoll, wie oben gezeigt. int-Objekte unterstützen es beispielsweise nicht.
- Protokoll
from operator import getitem
getitem( 0, 0 )
TypeError: 'int' object is not subscriptable
len( 0 )
TypeError: object of type 'int' has no len()
Unterschiede zwischen Attributen und Einträgen
Attribute werden mit ›getattr‹ gelesen, Einträge mit ›getitem‹.
Iterable und Sequenzen
Wenn eine Sequenz iterierbar ist (d.h. als Iterables verwendet werden kann), ist das Element an Position 0 normalerweise dasselbe Objekt wie das erste Objekt, das von einem Iterator für die Sequenz geliefert wird.
- Protokoll
from operator import getitem
first = next( iter( "xyzzy" ))
first
'x'
position_0 = getitem( "xyzzy", 0 )
position_0
'x'
- Protokoll
from operator import getitem
dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
'x'
next( iter( dir() ))
'__annotations__'
getitem( dir(), 0 )
'__annotations__'
Sequenz erlauben jedoch, anders als Iteratoren, einen wahlfreien Zugriff. Das heißt, es kann bei der Auswahl von Einträgen hin- und hergesprungen werden. Sie müssen nicht in aufsteigender Reihenfolge abgerufen werden und können auch nicht durch den Abruf verbraucht werden.
Tupel
Die einzelnen Einträge eines Tupels können mit »getitem« abgerufen werden.
- Protokoll
range( 20, 30 )
range(20, 30)
tuple( _ )
(20, 21, 22, 23, 24, 25, 26, 27, 28, 29)
from operator import getitem
print( getitem( _, 4 ))
24
print( getitem( _, 7 ))
27
Listen
Die einzelnen Einträge einer Liste können genau wie bei einem Tupel mit »getitem« abgerufen werden.
- Protokoll
from operator import getitem
getitem( list( range( 20, 30 )), 4 )
24
Auch Aufrufe von ›dir‹ ergeben ja eine Liste.
- Protokoll
from operator import getitem
import math
len( dir( math ))
60
getitem( dir( math ), 26 )
'floor'
Bereiche
Auch die einzelnen Einträge eines Bereichs können mit »getitem« abgerufen werden.
Der im Protokoll angegebene Bereich umfaßt alle Werte zwischen 400000000000000000 (einschließlich) und 900000000100000000 (ausschließlich), die durch wiederholte Addition von 321 zu 400000000000000000 erhalten werden können.
- Protokoll
from operator import getitem
getitem( range( 400000000000000000, 900000000100000000, 321 ), 700000 )
400000000224700000
Der riesige Bereich wird nicht manifestiert, so daß das Programm kaum Speicher braucht! (Würde man versuchen, den Bereich zu manifestieren, könnte es passieren, daß der Computer abstürzt.) Das range-Objekt enthält nur eine kurze Beschreibung des Bereichs. Trotzdem erlaubt »getitem« es, einzelne Werte aus dem Bereich so zu extrahieren, als wäre der Bereich ein manifestes Tupel.
Funktoren für Sequenzen
Einige Aufrufbare, wie »choice« sind für alle Sequenzen verfügbar. »choice« wählt einen Wert des Bereichs zufällig aus. Auch hier wird trotz des riesigen Bereichs nur ganz wenig Speicher benötigt, da der Bereich nicht manifestiert werden muß.
- Protokoll
from random import choice
choice( range( 400000000000000000, 900000000100000000, 321 ))
718379137792728649
- Protokoll
from random import choice
choice( "abc" )
'a'
- Protokoll
from random import choice
import math
choice( dir( math ))
'remainder'
Das heißt: Wann immer Sie aus einer irgendeiner Sequenz einen Eintrag zufällig auswählen wollen, können Sie ab jetzt »choice« verwenden! (Nur zu Übungszwecken soll in diesem Kurs doch manchmal nur »random« verwendet werden, und kein anderer Name aus dem Modul »random«.)
Übersicht Iterable und Aufrufbare
- Iteratoren (und damit auch Iterable)
- Ergebnisse von »enumerate«
from multiprocessing.pool import job_counter
job_counterfrom sys import stdin
stdin- Iterable
- alle Iteratoren
- str-Objekte (»"abc"«)
- list-Objekte (»dir()«)
- tuple-Objekte (»tuple()«)
from itertools import count
count()- range-Ergebnisse
- sorted-Ergebnisse
- map-Ergebnisse
- Sequenzen
- str-Objekte (»"abc"«)
- list-Objekte (»dir()«)
- tuple-Objekte (»tuple()«)
- range-Ergebnisse
- Aufrufbare, die Iteratoren akzeptieren
- »next«
- Aufrufbare, die Iterable akzeptieren
- »iter«
- »tuple«
- »sum« (nur Iterable, die Zahlen liefern)
- »min«
- »max«
- sorted( iter ) -> iter
- map( f, iter ) -> iter
- Aufrufbare, die Sequenzen akzeptieren
- getitem( sequence, index_or_slice ) -> object
- len( sequence ) -> integral_number
- choice( sequence ) -> object
Übungsaufgaben
/ Übungsaufgabe
Schreiben Sie einen Ausdruck, der mit einer Wahrscheinlichkeit von zirka 50 % ausgibt »Kino«, oder sonst »zu Hause bleiben«. Hierzu soll »choice« mit einem Tupel (angegeben durch eine kommagetrennte Auflistung von Ausdrücken) als Argument verwendet werden.
/ Übungsaufgabe
Schreiben Sie einen Ausdruck, bei dessen Auswertung eine Zahl zwischen 1 (einschließlich) und 6 (einschließlich) zufällig ausgewählt wird. Hierzu soll »range« und »choice« verwendet werden.
/ Übungsaufgabe *
Schreiben Sie einen Ausdruck, bei dessen Auswertung eine Sprache aus der folgenden Liste zufällig ausgewählt wird, und zwar mit einer Wahrscheinlichkeit, die der jeweiligen Zahl entspricht.
- Liste
liste = [
[ 'Englisch', 50 ],
[ 'Französisch', 5 ],
[ 'Italienisch', 5 ],
[ 'Japanisch', 5 ],
[ 'Russisch', 5 ],
[ 'Berlinisch', 1 ],
[ 'Hochchinesisch', 1 ],
[ 'Holländisch', 1 ],
[ 'Latein', 1 ],
[ 'Deutsch', 1 ],
[ 'Griechisch', 1 ],
[ 'Spanisch', 1 ],
[ 'Portugiesisch', 1 ],
[ 'Arabisch', 1 ],
[ 'Polnisch', 1 ],
[ 'Hebräisch', 1 ],
[ 'Türkisch', 1 ],
]