lehrkraefte:snr:informatik:glf22:python:listen-altes-material

Listen

Welche Ausgabe erwartest du?

a = [0, 1, 2, 3]
b = a
print(a)
print(b)
b[3] = 4
print(a)
print(b)
a.append(7)
print(a)
print(b)

Vermutlich überrascht dich die Ausgabe. Wir erklären das im Folgenden.

Man sollte sich dies so vorstellen: In der ersten Zeile des obigen Programms wird die Liste [0, 1, 2, 3] irgendwo im Speicher angelegt, an einer gewissen Speicheradresse (das ist eine gewisse Position im Speichermedium, so wie eine Adresse eine gewisse Position auf der Welt kodiert). Beispielsweise könnte sie an der Speicheradresse 6 stehen:

Die Variable a wird mit dem Befehl a = [0, 1, 2, 3] mit dieser Speicheradresse verknüpft (verknüpfen bedeutet, dass der Computer in einer Art Tabelle zu jedem Variablennamen die zugehörige Speicheradresse kennt). Hilfreich ist es, sich diese Verknüpfung wie im obigen Bild als Pfeil auf die entsprechende Position im Speicher vorzustellen. Man sagt deswegen auch, dass a auf diese Speicheradresse verweist. Der Wert von a ist das an dieser Speicheradresse gespeicherte Datum [0, 1, 2, 3].

Das obige Bild malt man kurz wie folgt:

a ---------> [0, 1, 2, 3]

Der Befehl b = a bewirkt, dass b auf dieselbe Speicheradresse verweist.

a ---------> [0, 1, 2, 3] <--------- b

Der Befehl b[3] = 4 bewirkt das folgende: In der Liste, die sich an der zu b gehörenden Speicheradresse befindet, wird das Element mit Index 3 auf den neuen Wert 4 gesetzt. Die Speicheradresse der Liste bleibt dabei aber unverändert: Sowohl a als auch von b verweisen weiterhin auf diese Speicheradresse.

a ---------> [0, 1, 2, 4] <--------- b

Analoges gilt, wenn wir mit dem Befehl a.append(7) etwas an die Liste anhängen, die sich unter der zu a gehörenden Speicheradresse befindet.

a ---------> [0, 1, 2, 4, 7] <--------- b

Dass das bisher Gesagte stimmt, kann man mit Hilfe der Funktion id (für Identität oder identity) testen, die im Wesentlichen die Speicheradresse einer Variablen liefert: Beispielsweise ist id(a) die Speicheradresse von a.

a = [0, 1, 2, 3]
b = a
print(a)
print(id(a))
print(b)
print(id(b))
b[3] = 4
print(a)
print(id(a))
print(b)
print(id(b))
a.append(7)
print(a)
print(id(a))
print(b)
print(id(b))

In diesem Sinne sind Listen mutable (was man deutsch als veränderlich oder per Fremdwort als mutabel bezeichnen mag): Verweist eine Variable, etwa a, auf eine solche Liste, so kann man diese Liste mit Befehlen wie a[3] = … oder a.append(…) oder a.pop(…) verändern.

Im Gegensatz dazu sind Integers, Floats, Strings, Booleans immutable (also unveränderlich oder immutabel): (Veränderungsbefehle wie bei Listen gibt es nicht.)

a = 3
b = a
b = 4
print(a)
print(id(a))
print(b)
print(id(b))

Der Befehl b = a bewirkt wieder, dass a und b auf dieselbe Speicheradresse verweisen:

a ---------> 3 <--------- b

Da a als Integer-Variable immutabel ist, kann der Befehl b = 4 den Inhalt der entsprechenden Speicheradresse nicht verändern. Stattdessen wird an einer freien Speicheradresse 4 als Wert der Variablen b gespeichert.

Wovon hängt es ab, ob ein Datentyp (Beispiele für Datentypen sind strings, integers, floats, Booleans, lists) mutabel oder immutabel ist? Dies ist schlicht von den Entwicklern der Sprache Python so festgesetzt worden.

Will man wirklich eine Kopie einer gegebenen Liste (an einer neuen Speicheradresse) erzeugen, so tut es1) der Befehl b = a[:]:

a = [0, 1, 2, 3]
b = a[:]
b[3] = 4
print(a)
print(id(a))
print(b)
print(id(b))
a.append(7)
print(a)
print(id(a))
print(b)
print(id(b))

Wer mehr wissen will, mag hier weiterlesen.

2aLM und 2dNP bis hier am 27.10.2021 (jedenfalls einige)

n = 4
s = "Hallo"
zahlen = list(range(1, n))

Ergänze diesen Programmanfang so, dass eine Liste erzeugt und ausgegeben wird, deren Elemente wiederum Listen sind. Der i-te Eintrag dieser Liste soll aus der Liste zahlen entstehen, indem man dort vor der i-ten Position den String s als Element einfügt (im Fall i=n soll der String s am Ende angefügt werden). Die Ausgabe soll also wie folgt aussehen (sie soll sich aber natürlich ändern, wenn man n oder s ändert):

[['Hallo', 1, 2, 3], [1, 'Hallo', 2, 3], [1, 2, 'Hallo', 3], [1, 2, 3, 'Hallo']]

Schreibe ein Programm, das alle Permutation einer vorgegebenen Liste berechnet. Die Permutationen der Liste [1,2,3,4] sind beispielsweise wie folgt gegeben:

[1, 2, 3, 4], [1, 2, 4, 3], [1, 3, 2, 4], [1, 3, 4, 2], [1, 4, 2, 3], [1, 4, 3, 2],

[2, 1, 3, 4], [2, 1, 4, 3], [2, 3, 1, 4], [2, 3, 4, 1], [2, 4, 1, 3], [2, 4, 3, 1],

[3, 1, 2, 4], [3, 1, 4, 2], [3, 2, 1, 4], [3, 2, 4, 1], [3, 4, 1, 2], [3, 4, 2, 1],

[4, 1, 2, 3], [4, 1, 3, 2], [4, 2, 1, 3], [4, 2, 3, 1], [4, 3, 1, 2], [4, 3, 2, 1]

Bemerkung: Dies ist vermutlich recht schwierig. Eine mögliche Lösung ist

hier

hier

zuPermutierendeElemente = range(1, 5)
ausgabeParameter = 6
 
permutationen = [[]]
for x in zuPermutierendeElemente:
    neuepermutationen = []
    for p in permutationen:
        for i in range(len(p) + 1): 
            q = p[:]
            q.insert(i, x)
            neuepermutationen.append(q)
    permutationen = neuepermutationen[:]
 
permutationen.sort() # Dieser Befehl sortiert die Liste. Er kann auch weggelassen werden.     
print(permutationen)
print('')
 
# Die Liste aller Permutationen in einer Zeile auszugeben war mir zu unübersichtlich...
for i in range(len(permutationen) // ausgabeParameter):
    ausschnitt = permutationen[ausgabeParameter * i: ausgabeParameter * i + ausgabeParameter]
    print(', '.join(map(str, ausschnitt))) # Dies ist relativ kompliziert - bitte nachfragen!

angegeben - diese zu verstehen (Lernen am Beispiel) ist ebenfalls eine sehr lohnende Übung!

  • Auf der Seite Listen von Herrn Blöchliger sind weitere Aufgaben und Erklärungen und Lösungsvorschläge.

(Gemeinsam besprechen?)

Schreibe ein Programm, das eine vorgegebene Liste von Zahlen (oder Zeichenketten) sortiert OHNE die Listensortierfunktion sort() zu verwenden.

Hinweis: Wie sortierst du einen Stapel von Karten? Bringe dein Verfahren dem Computer bei! (Es gibt ziemlich viele Verfahren!)

Das bekannte |magische Quadrat von Albrecht Dürer wird im folgenden Code-Teil als doppelt verschachtelte Liste gespeichert und auf zwei mehr oder weniger lesbare Arten ausgegeben.

q = [[16,3,2,13],\
     [5,10,11,8],\
     [9,6,7,12],\
     [4, 15, 14, 1]]
 
 
print(q)
print("")
 
for zeile in q:
    print(zeile)

Ergänze diesen Code so, dass die Summen der Einträge aller Zeilen und aller Spalten berechnet werden (was dann zeigt, dass es sich wirklich um ein magisches Quadrat handelt). Schön formatiert könnte die Aussage etwa so aussehen:

  16   3   2  13 |   34
   5  10  11   8 |   34
   9   6   7  12 |   34
   4  15  14   1 |   34
-----------------+
  34  34  34  34

Challenge (für die Herbstferien?): Schreibe ein Programm, dass alle 880 magischen 4×4-Quadrate berechnet.

Bereits bekannte Sachverhalte zu Listen und Strings

Extraktion von Teillisten

  • Extraktion von Teillisten mit <Name der Liste>[<Startindex>:<Endindex>], wobei die Teilliste beim Startindex beginnt und eine Position vor dem Endindex endet, z. B.:
    • meineListe[1:4] liefert die Liste [“Berta”, “Caesar”, “Dora”]
    • als Indizes sind ähnlich wie im vorigen Punkt auch negative Zahlen erlaubt: Die Befehle meineListe[1:-3] oder meineListe[-6:4] oder meineListe[-6:-3] liefern ebenso die Liste [“Berta”, “Caesar”, “Dora”].
  • Bei der Extraktion von Teillisten dürfen Start- oder Endindex weggelassen werden.
    • Lässt man den Startindex weg, so wird er “per default” minimal sinnvoll (also auf 0) gesetzt. Beispielsweise liefert meineListe[:4] die Liste [“Anton”, “Berta”, “Caesar”, “Dora”]. Dieselbe Liste erhält man mit meineListe[:-3]
    • Lässt man den Endindex weg, so wird er “per default” maximal sinnvoll (also auf die Länge der Liste) gesetzt. Beispielsweise liefern meineListe[4:] und meineListe[-3:] die Liste [“Emil”, “Friedrich”, “Gustav”].

Ausserdem sei bekannt, dass der Befehl meineListe[::-1] die umgekehrte Liste [“Gustav”, “Friedrich”, “Emil”, “Dora”, “Caesar”, “Berta”, “Anton”] liefert.2)

Zu Strings alias Zeichenketten

  • Bezeichnet s einen String in Python, so liefert s.lower() denjenigen String, in dem alle Großbuchstaben von s durch Kleinbuchstaben ersetzt wurden.
    • Beispiel: Für s = “Goethes Faust, Teil I” liefert s.lower() den String “goethes faust, teil i”.
  • Ähnlich wie oben bei Listen kann man auf die einzelnen Zeichen eines Strings bzw. einen Teil des Strings zugreifen.
    • Für s wie oben liefert
      • s[8] das Zeichen (alias den String der Länge Eins) “F”,
      • s[8:13] den String “Faust”,
      • s[-6:] den String “Teil I”,
      • s[::-1] den String “I lieT ,tsuaF sehteoG”.
  • Die Funktion len liefert die Länge eines Strings, z. B. liefert len(s) im obigen Beispiel die Zahl 21.

Retour zur Hauptseite

Ideen

for-loop über Liste

  • Strings? length, Substrings mit [::] (alles dann wieder bei Listen); replace, find, uppercase, split, Befehl dir erklären. Dann “Drei Chinesen …” ersetze. Uppercase.
  • “Brauche” Listen: String-Befehle, rauskriegen etwa per dir(s) wobei s String ist

1)
Bei verschachtelten Listen muss man besser aufpassen und die Befehle copy oder deepcopy aus dem Modul copy verwenden: Die unterschiedlichen Effekte sind hier illustriert:
import copy
 
a = [1, 2, ['x', 'y']]
b = a
c = a[:]
d = copy.copy(a)
# Meines Wissens besteht zwischen den Objekten a[:] und copy.copy(a) kein Unterschied.
e = copy.deepcopy(a)
a.append('z')
a[2].append(3)
print(a)
print(b)
print(c)
print(d)
print(e)
print(id(a))
print(id(b))
print(id(c))
print(id(d))
print(id(e))
2)
Für diejenigen, die es genau wissen möchten oder sich vage erinnern: Mit Hilfe der Syntax <Name der Liste>[<Startindex>:<Endindex>:<Schrittweite>] kann man eine Schrittweite als zusätzlichen dritten Parameter übergeben:
  • meineListe[1:5:2] liefert die Liste [“Berta”, “Dora”].
  • ACHTUNG: Hierbei sind auch negative Schrittweiten erlaubt: meineListe[5:1:-1] liefert die Liste [“Friedrich”, “Emil”, “Dora”, “Caesar”].
  • Lässt man bei positiver Schrittweite Start- bzw. Endindex weg, so wird dieser (ähnlich wie oben) minimal bzw. maximal gesetzt:
    • meineListe[::2] liefert dasselbe wie meineListe[0:7:2], nämlich die aus jedem zweiten Element bestehende Teilliste, also [“Anton”, “Caesar”, “Emil”, “Gustav”].
  • ACHTUNG: Lässt man bei negativer Schrittweite Start- bzw. Endindex weg, so wird dieser maximal bzw. minimal (was hier -1 bedeutet) gesetzt. Dies erklärt, dass meineListe[::-1] die umgekehrte Liste liefert.
  • lehrkraefte/snr/informatik/glf22/python/listen-altes-material.txt
  • Last modified: 2022/09/26 20:44
  • by Olaf Schnürer