15. Einführung in Listen

15.1. Datentypen

Bis jetzt gab es in diesem Buch vier Datentypen:

  • Strings (Im Englischen steht String kurz für einen „string of characters“, also eine Aufeinanderfolge von Zeichen. Im Deutschen sagt man dazu auch Zeichenkette. Viele Programmierer nennen den Datentyp inzwischen String, weil Zeichenkettenvariablen in vielen Programmiersprachen mit String oder string deklariert werden. Normale Leute denken bei Zeichenketten an Text.)

  • Integer (Ganze Zahlen)

  • Floating Point (Gleitkommazahlen)

  • Boolean (Wahrheitswerte)

Python kann den Datentyp eines Werts mit der Funktion type anzeigen. Zum Beispiel, welchen Datentyp hat 3?

# Print the type of data a 3 is:
print(type(3))
<class 'int'>

In diesem Buch wird die type-Funktion weniger gebraucht, aber sie hilft die bis jetzt eingeführten Datentypen zu zeigen.

Hier setzen wir x auf die vier Datentypen, die wir bis jetzt verwendet haben, und rufen die type-Funktion auf, um zu sehen wie Python die Daten einteilt:

x = 3
print("x =", x, "and is of type:", type(x))

x = 3.145
print("x =", x, "and is of type:", type(x))

x = "Hi there"
print("x =", x, "and is of type:", type(x))

x = True
print("x =", x, "and is of type:", type(x))

Die Ausgabe:

x = 3 and is of type: <class 'int'>
x = 3.145 and is of type: <class 'float'>
x = Hi there and is of type: <class 'str'>
x = True and is of type: <class 'bool'>

Bemerkung

Ist mehr als eine Münze einzusammeln? Verwende eine Liste!

Die beiden in diesem Kapitel neu eingeführten Datentypen sind Listen und Tupel. Listen sind ähnlich zu dem, was andere Programmiersprachen Arrays oder Felder nennen. Eine Liste kann in der Größe verändert werden, aber ein Array nicht. Ein Kurs zu Datenstrukturen wird dir die Details beibringen, aber das geht über dieses Buch hinaus. Probiere die folgenden Anweisungen in einer interaktiven Python-Shell aus und sieh dir an, was ausgegeben wird:

x = (2, 3, 4, 5)
print("x =", x, "and is of type:", type(x))

x = [2, 3, 4, 5]
print("x =", x, "and is of type:", type(x))

Die Ausgabe:

x = (2, 3, 4, 5) and is of type: <class 'tuple'>
x = [2, 3, 4, 5] and is of type: <class 'list'>

15.2. Arbeiten mit Listen

Du hast Einkaufslisten, Todo-Listen und Listen mit Dingen, die du machen willst, wenn du in Rente geht, geschrieben. Wie erzeugst du eine solche Liste auf dem Rechner?

../../_images/grocery_list.png

Sogar Rechner verwenden Listen

Um eine Liste zu erstellen und auszugeben, versuche folgendes:

x = [10, 20]
print(x)

Die Ausgabe:

[10, 20]

Um ein einzelnes Element einer Liste auszugeben:

print(x[0])

Die Ausgabe:

10

Diese Nummer mit der Position des Elements wird Index genannt. Beachte, dass die Positionen bei Null beginnen, deshalb hat eine Liste mit zehn Elementen kein Element an der Postion [10]. Nur die Positionen [0] bis [9]. Es kann sehr irritierend sein, eine Liste mit zehn Elementen zu erzeugen und dann kein Element 10 zu haben, aber die meisten Programmiersprachen beginnen mit der 0 zu zählen statt mit der 1.

Denke bei einer Liste an einen Eierkarton, der Zahlen enthält, wie in Abbildung 7.2 gezeigt. Die Werte werden in den einzelnen Vertiefungen gespeichert und auf der Seite des Behälters stehen Zahlen von 0 ab, die die Position der Vertiefungen markieren.

Achtung

Verwechsle nicht den Index und den Wert!

Erinnere dich, es gibt zwei Mengen von Zahlen, die man beachten muss, wenn man mit Listen arbeitet: die Position und den Wert. Die Position, auch Index genannt, verweist wo der Wert ist. Der Wert ist die tatsächliche Zahl, die an dieser Position gespeichert ist. Stelle sicher, ob du die Position oder den Wert benötigst, wenn du mit Listen oder Arrays arbeitest.

Es ist einfach, den Wert an einer bestimmten Position zu bekommen. Es ist aber schwerer die Position eines gegebenen Werts zu bekommen. Kapitel 15 widmet sich dem Thema, wie man die Position eines bestimmten Werts findet.

../../_images/ice_cube_tray.png

Listen sind wie Eiswürfelbehälter

Du kannst die Elemente am Ende eines Arrays mit negativen Zahlen erreichen. (Nicht alle Programmiersprachen unterstützen das.) Zum Beispiel:

x = [10, 20, 30]
print(x[-1])

Die Ausgabe:

30

Ein Programm kann einen neuen Wert an ein einzelnes Element einer Liste zuweisen. Im Fall unten wird an die Position Null (nicht Eins) die Zahl 22 zugewiesen.

x = [1, 2]
print(x)

x[0] = 22
print(x)
[1, 2]
[22, 2]

Ein Programm kann auch ein Tupel erzeugen. Dieser Datentyp funktioniert genau wie eine Liste, aber mit zwei Unterschieden. Zum einen wird ein Tupel mit runden Klammern statt mit eckigen erzeugt. Zum anderen kann man ein Tupel nicht mehr verändern, wenn es einmal erzeugt wurde. Siehe unten:

x = (1, 2)
print(x)

x[0] = 22
print(x)
[1, 2]
Traceback (most recent call last):
  File "<pyshell#18>", line 4, in <module>
    x[0] = 22
TypeError: 'tuple' object does not support item assignment

Wie man aus der Ausgabe des Codes oben sehen kann, können wir einem Element in einem Tupel keinen neuen Wert zuordnen. Warum gibt es diese Einschränkung? Zum einen kann ein Rechner das Programm schneller abarbeiten, wenn er weiß, dass die Werte sich nicht ändern werden. Zum anderen gibt es Listen, bei denen wir nicht möchten, dass sich die Werte ändern können. Eine solche Liste ist die RGB-Farbe für Rot. Die Farbe Rot ändert sich nicht, deshalb ist es besser die RGB-Werte in einem Tupel zu speichern.

15.3. Erstelle eine leere Liste

Ab und an müssen wir eine Liste erstellen, die leer ist. Wir werden das in Kürze verwenden und mit einer leeren Liste anfangen und sie dann füllen. Wie erstellen wir eine leere Liste? Einfach:

# Create an empty list
my_list = []

15.4. Durch eine Liste iterieren (Wiederholung mit Listenelementen)

Wenn ein Programm durch alle Elemente einer Liste iterieren soll, um sie zum Beispiel auszudrucken, dann gibt es zwei Arten von Schleifen, die das können.

Die erste Methode ist mit einer „for-each“-Schleife (Wiederholung mit Aufzählung der Elemente). Diese Schleifenart nimmt eine Sammlung von Elementen und wiederholt den Code einmal mit jedem Element. Sie wird eine Kopie des Elements in einer Variablen zur Ausführung erstellen.

Das Format der Anweisung ist:

for item_variable in list_name:

Hier sind ein paar Beispiele:

my_list = [101, 20, 10, 50, 60]
for item in my_list:
    print(item)
101
20
10
50
60

Programme können Zeichenketten auch in Listen speichern:

my_list = ["Spoon", "Fork", "Knife"]
for item in my_list:
    print(item)
Spoon
Knife
Fork

Listen können andere Listen als Element beinhalten. Der folgende Programmcode iteriert über alle Elemente in der Hauptliste, aber nicht in den Unterlisten.

my_list = [[2, 3], [4, 3], [6, 7]]
for item in my_list:
    print(item)
[2,3]
[4,3]
[6,7]

Der andere Weg durch eine Liste zu iterieren ist, eine Indexvariable zu verwenden und direkt auf die List zuzugreifen anstatt eine Kopie jedes Elements zu erstellen. Um eine Indexvariable zu verwenden, zählt das Programm von 0 bis zur Länge der Liste. Wenn es zehn Elemente gibt, muss die Schleife von 0 bis 9 für insgesamt zehn Elemente gehen.

Die Länge einer Liste kann man mit der len-Funktion bestimmen. Kombiniert mit der range-Funktion erlaubt das, über alle Elemente der Liste zu iterieren.

my_list = [101, 20, 10, 50, 60]
for index in range(len(my_list)):
    print(my_list[index])
101
20
10
50
60

Diese Methode ist komplexer, aber auch mächtiger. Weil wir direkt mit den Listenelementen arbeiten statt einer Kopie, kann die Liste verändert werden. Die Wiederholung mit Aufzählung der Elemente (for-each-Schleife) erlaubt keine Veränderung der originalen Liste.

15.5. Schleife mit Index und Element

Wenn du sowohl den Index, wie in for i in range, und das Element, wie in for item in my_list, haben willst, ist der richtige Pythoneske Weg, die enumerate-Funktion wie folgt zu verwenden :

for index, value in enumerate(my_list):
    print(index, value)

15.6. An eine Liste anhängen

Neue Elemente können an eine Liste mit der append-Anweisung angefügt werden (aber nicht an ein Tupel). Zum Beispiel:

my_list = [2, 4, 5, 6]
print(my_list)
my_list.append(9)
print(my_list)
[2, 4, 5, 6]
[2, 4, 5, 6, 9]

Randnotiz: Wenn die Performanz beim Anfügen entscheidend ist, dann ist es wichtig zu verstehen, wie Listen implementiert werden. Wenn zum Beispiel die Liste als ein Array-Typ implementiert ist, dann ist das Anfügen, wie ein Ei in einen vollen Eierkarton zu packen. Es muss erst ein neuer Karton mit dreizehn Plätzen erstellt werden. Dann werden die zwölf Eier in den neuen Karton umgepackt und das dreizehnte Ei dazu gepackt. Zum Schluss wird noch der alte Eierkarton recycelt. Weil dies alles hinter den Kulissen in einer Funktion durchgeführt wird, können Programmierer dies vergessen und lassen den Rechner die ganze Arbeit machen. Es wäre effizienter, den Rechner von Anfang an anzuweisen, einen Karton mit genug Plätzen zu erstellen. Glücklicherweise implementiert Python Listen nicht als Array-Typ, aber es ist wichtig im Datenstrukturen-Kurs im nächsten Semester aufzupassen und zu lernen, wie dies alles funktioniert.

Um eine Liste von Null an zu erstellen, ist es notwendig, eine leere Liste zu erstellen und dann die Liste mit der append-Funktion basierend auf den Benutzereingaben aufzubauen:

Erstellen einer Liste mit Zahlen von Benutzereingaben
# Create an empty list
my_list = []

for i in range(5):
    user_input = input( "Enter an integer: ")
    user_input = int(user_input)
    my_list.append(user_input)
    print(my_list)
Enter an integer: 4
[4]
Enter an integer: 5
[4, 5]
Enter an integer: 3
[4, 5, 3]
Enter an integer: 1
[4, 5, 3, 1]
Enter an integer: 8
[4, 5, 3, 1, 8]

Wenn ein Programm ein Array einer festgelegten Länge, alle Elemente mit demselben Wert, erstellen soll, dann hilft der folgende Trick:

Erstelle ein Array mit 100 Nullen
1
2
# Create an array with 100 zeros.
my_list = [0] * 100

15.7. Summieren oder Modifizieren einer Liste

Die Gesamtsumme eines Array zu berechnen, ist eine häufige Operation. Hier ist, wie es gemacht wird:

Summieren der Werte in einer Liste v1
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Copy of the array to sum
my_list = [5, 76, 8, 5, 3, 3, 56, 5, 23]

# Initial sum should be zero
list_total = 0

# Loop from 0 up to the number of elements
# in the array:
for index in range(len(my_list)):
    # Add element 0, next 1, then 2, etc.
    list_total += my_list[index]

# Print the result
print(list_total)

Das Gleiche kann mit einer for-Schleife, die über das Array iteriert statt durch den Bereich zu zählen, erreicht werden:

Summieren der Werte in einer Liste v2
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Copy of the array to sum
my_list = [5, 76, 8, 5, 3, 3, 56, 5, 23]

# Initial sum should be zero
list_total = 0

# Loop through array, copying each item in the array into
# the variable named item.
for item in my_list:
    # Add each item
    list_total += item

# Print the result
print(list_total)

Zahlen in einem Array können auch mit einer for-Schleife verändert werden:

Verdopplung aller Zahlen in einer Liste
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Copy of the array to modify
my_list = [5, 76, 8, 5, 3, 3, 56, 5, 23]

# Loop from 0 up to the number of elements
# in the array:
for index in range(len(my_list)):
    # Modify the element by doubling it
    my_list[index] = my_list[index] * 2

# Print the result
print(my_list)

Die Version 2 verdoppelt allerdings nicht die Werte in einem Array. Warum? Weil item eine Kopie eines Elements im Array ist. Der Code unten verdoppelt die Kopie, nicht das originale Array-Element.

Schlechter Code, der nicht alle Werte der Zahlen in einer Liste verdoppelt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Copy of the array to modify
my_list = [5, 76, 8, 5, 3, 3, 56, 5, 23]

# Loop through each element in myArray
for item in my_list:
    # This doubles item, but does not change the array
    # because item is a copy of a single element.
    item = item * 2

# Print the result
print(my_list)

15.8. Zeichenketten-Aufschnitt

Zeichenketten sind tatsächlich Listen von Zeichen. Sie können genau wie Listen, mit jedem Zeichen als separates Element, behandelt werden. Führe den folgenden Code mit beiden Versionen von x aus:

Auf Strings als Liste zugreifen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
x = "This is a sample string"
#x = "0123456789"

print("x=", x)

# Accessing the first character ("T")
print("x[0]=", x[0])

# Accessing the second character ("h")
print("x[1]=", x[1])

# Accessing from the right side ("g")
print("x[-1]=", x[-1])

# Access 0-5 ("This ")
print("x[:6]=", x[:6])
# Access 6 to the end ("is a sample string")
print("x[6:]=", x[6:])
# Access 6-8
print("x[6:9]=", x[6:9])

Strings in Python können mit einigen mathematischen Operatoren verknüpft werden. Probiere den folgenden Code aus und sieh dir an, was Python macht:

Addition und Multiplikation von Strings
1
2
3
4
5
6
7
8
a = "Hi"
b = "There"
c = "!"
print(a + b)
print(a + b + c)
print(3 * a)
print(a * 3)
print((a * 2) + (b * 2))

Man kann die Länge eines Strings bestimmen. Dies ist auch mit jedem beliebigen Typ von Array möglich.

Die Länge eines Strings oder einer Liste bestimmen
1
2
3
4
5
a = "Hi There"
print(len(a))

b = [3, 4, 5, 6, 76, 4, 3, 3]
print(len(b))

Da ein String ein Array ist, kann ein Programm über jedes Zeichen iterieren genau wie bei einem Array:

for character in "This is a test.":
    print(character)

Übung: Beginne mit dem folgenden Code:

1
2
months = "JanFebMarAprMayJunJulAugSepOctNovDec"
n = int(input("Enter a month number: "))

Gib die Abkürzung für die Monatsnummer aus, die der Benutzer eingibt. (Berechne die Anfangsposition im String, verwende dann die Information, die wir gerade gelernt haben, um den korrekten Teilstring auszugeben.)

15.9. Geheimcodes

Dieser Code gibt jedes Zeichen eines Strings einzeln aus:

1
2
3
4
plain_text = "This is a test. ABC abc"

for c in plain_text:
    print(c, end=" ")

Rechner speichern nicht wirklich Zeichen eines Strings im Speicher. Rechner speichern eine Folge von Zahlen. Jede Zahl repräsentiert einen Buchstaben. Ein System, das Rechner verwenden, um Zahlen in Buchstaben um zu wandeln, wird Unicode genannt. Der ganze Name ist „Universal Character Set Transformation Format 8-Bit“, üblicherweise als UTF-8 abgekürzt.

Diese Unicode-Tabelle deckt das westliche Alphabet mit den Zahlen 0 - 127 ab. Jeder westliche Buchstabe wird mit einem Byte im Speicher repräsentiert. Umlaute gehören nicht dazu. Sie benötigen wie andere Alphabete (zum Beispiel kyrillisch) mehrere Bytes zur Repräsentation jedes Zeichens. Ein Teil der Unicode-Tabelle steht unten:

Wert

Zeichen

Wert

Zeichen

Wert

Zeichen

Wert

Zeichen

40

(

61

=

82

R

103

g

41

)

62

>

83

S

104

h

42

63

?

84

T

105

i

43

64

@

85

U

106

j

44

,

65

A

86

V

107

k

45

66

B

87

W

108

l

46

.

67

C

88

X

109

m

47

/

68

D

89

Y

110

n

48

0

69

E

90

Z

111

o

49

1

70

F

91

[

112

p

50

2

71

G

92

113

q

51

3

72

H

93

]

114

r

52

4

73

I

94

^

115

s

53

5

74

J

95

_

116

t

54

6

75

K

96

`

117

u

55

7

76

L

97

a

118

v

56

8

77

M

98

b

119

w

57

9

78

N

99

c

120

x

58

:

79

O

100

d

121

y

59

;

80

p

101

e

122

z

60

<

81

Q

102

f

Für mehr Information zu ASCII (das die gleichen Werte wie Unicode für das Western-Alphabet verwendet) siehe:

http://de.wikipedia.org/wiki/ASCII

Ein Video, das die Schönheit von Unicode erklärt, findest du hier:

http://hackaday.com/2013/09/27/utf-8-the-most-elegant-hack

Der nächste Code konvertiert jeden Buchstaben im vorigen Beispiel in seinen Ordinalwert unter Verwendung von UTF-8:

plain_text = "This is a test. ABC abc"

for c in plain_text:
    print(ord(c), end=" ")

Das nächste Programm nimmt jeden UTF-8-Wert und addiert eins zu ihm. Danach gibt es den neuen UTF-8-Wert aus und konvertiert den Wert zurück in einen Buchstaben.

plain_text = "This is a test. ABC abc"

for c in plain_text:
    x = ord(c)
    x = x + 1
    c2 = chr(x)
    print(c2, end="")

Das nächste Programm nimmt jeden UTF-8-Wert, addiert eins dazu und konvertiert den Wert zurück in einen Buchstaben.

../../_images/encrypt.png
simple_encryption.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Sample Python/Pygame Programs
# Simpson College Computer Science
# http://programarcadegames.com/
# http://simpson.edu/computer-science/

# Explanation video: http://youtu.be/sxFIxD8Gd3A

plain_text = "This is a test. ABC abc"

encrypted_text = ""
for c in plain_text:
    x = ord(c)
    x = x + 1
    c2 = chr(x)
    encrypted_text = encrypted_text + c2
print(encrypted_text)

Zum Schluss nimmt das letzte Programm jeden UTF-8-Wert, zieht eins davon ab und konvertiert den Wert dann zurück in einen Buchstaben. Wenn man die Ausgabe des vorigen Programms in dieses füttert, dann dekodiert es den Text, den das vorige Programm kodiert hat.

../../_images/decrypt.png
simple_decryption.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Sample Python/Pygame Programs
# Simpson College Computer Science
# http://programarcadegames.com/
# http://simpson.edu/computer-science/

# Explanation video: http://youtu.be/sxFIxD8Gd3A

encrypted_text = "Uijt!jt!b!uftu/!BCD!bcd"

plain_text = ""
for c in encrypted_text:
    x = ord(c)
    x = x - 1
    c2 = chr(x)
    plain_text = plain_text + c2
print(plain_text)

15.10. Assoziative Arrays

Python ist nicht auf die Verwendung von Zahlen als Index eingeschränkt. Es ist auch möglich, ein assoziatives Array zu verwenden. Ein assoziatives Array funktioniert wie folgt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Create an empty associative array
# (Note the curly braces.)
x = {}

# Add some stuff to it
x["fred"] = 2
x["scooby"] = 8
x["wilma"] = 1

# Fetch and print an item
print(x["fred"])

In diesem Kurs wirst du nicht wirklich assoziative Arrays benötigen, aber ich denke es ist wichtig, zu zeigen, dass es möglich ist.