21. Methoden von Dictionaries

Häufig nützlich sind Listen der Schlüssel oder Werte eines Dictionaries.

>>> d.values()
['1', '+', '2']
>>> d.keys()
['eins', 'plus', 'zwei']
>>> d.items()
[('eins', '1'), ('plus', '+'), ('zwei', '2')]

Die von d.items() zurückgegebenen Paare sind Tupel.

Die Methode has_key prüft, ob ein Schlüssel vorhanden ist:

>>> if d.has_key('minus'):
...   m = d['minus']
... else:
...   m = None
>>> print m
None

Solche Konstruktionen kommen häufig vor, daher die Abkürzung

>>> m = d.get('minus', None)
>>> m = d.setdefault('minus', None)

Im zweiten Fall wird dict[’m’] als Seiteneffekt der Wert None zugewiesen.

Praktisch ist setdefault besonders, wenn man als Werte irgendwelche veränderbaren Datenstrukturen hat. Will man etwa einfach eine leere Liste anlegen, wenn ein Schlüssel noch nicht vorhanden ist, ansonsten an die bestehende Liste anhängen, ginge das so:

d.setdefault(key, []).append(whatever)

was kürzer und auch nicht unverständlicher ist als das äquivalente

if d.has_key(key):
  d[key].append(whatever)
else:
  d[key] = [whatever]

Dictionaries lassen sich kopieren:

>>> d2 = d.copy()
>>> d2["drei"] = "3"
>>> d2
{'drei': '3', 'eins': '1', 'plus': '+',
'zwei': '2'}
>>> d
{'eins': '1', 'plus': '+', 'zwei': '2'}

Zuweisung ohne Kopieren würde wieder zu zwei Referenzen auf dasselbe Dictionary führen:

>>> d1 = d
>>> d1["drei"] = "3"
>>> d
{'drei': '3', 'eins': '1', 'plus': '+',
'zwei': '2'}

Manchmal nützlich ist update, das die Werte aus einem Dictionary mit denen aus einem anderen überschreibt:

>>> d = {"eins": '1', "zwei": '2',
... "plus": '+'}
>>> d.update({"minus": "-", "eins": "e"})
>>> d
{'eins': 'e', 'plus': '+', 'minus': '-',
'zwei': '2'}

Übungen zu diesem Abschnitt

Ihr solltet euch wenigstens an den rötlich unterlegten Aufgaben versuchen

(1)

Häufig möchte man Verteilungen von Wörtern bestimmen, d.h. Abbildungen von Wörtern auf die Anzahl ihres Vorkommens. Dazu könnte etwa folgender Code dienen, in dem w das zu zählende Wort ist und dist die Verteilung, die natürlich als Dictionary modelliert ist:

if dist.has_key(w):
  dist[w] = dist[w]+1
else:
  dist[w] = 1

Wozu braucht es die Bedienung auf has_key überhaupt? Und wie lässt sich das Ganze kürzer formulieren?

(2)

Dictionaries eignen sich gut zur Modellierung von Funktionen, deren Werte nur an endlich vielen (besser wenigen) Stellen bekannt sein müssen. Dies gilt insbesondere dann, wenn die tatsächliche Berechnung der Funktion zeitaufwändig oder unmöglich ist.

Schreibt eine Funktion tabulate(valList, fct) -> dict, die eine Liste von Werten und eine Funktion nimmt und ein Dictionary zurückgibt, in dem jeder Wert w in valList auf fct(w) abgebildet wird. Diese Funktion soll etwa folgendes tun:

>>> def sqr(x):
...     return x*x
...
>>> tabulate(range(10), sqr)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

Beachtet, dass hinter sqr keine Klammern stehen: Gemeint ist die Funktion selbst (das, was der Name sqr referenziert) und nicht das Ergebnis eines Aufrufs der Funktion. Probiert auch andere Funktionen aus, die euch so einfallen.

Auf der nächsten Folie werdet ihr sehen, wie ihr all die spannenden Funktionen aus dem Math-Modul für dieses Spiel verwenden könnt.

(3)

Nehmt jetzt an, ihr hättet ein Dictionary, in dem weitere Dictionaries stehen. Ein Anwendungsfall wäre das Zählen von Bigrammen, also aufeinanderfolgenden Wörtern. Der Schlüssel im “Haupt-Dictionary” ist das erste Wort der Bigramme, mit dem man dann ein weiteres Dictionary erhält, in dem das jeweils zweite Wort steht. Dessen Wert könnte dann etwa die Häufigkeit des betreffenden Bigramms sein.

Schreibt eine Funktion countBigram(w1, w2, dist) -> None, das w1 und w2 in der beschriebenen Weise in dist einhängt.

(4)

Erklärt die Ausgabe von

>>> l = [{}]*4
>>> l[0]['n'] = 3
>>> l

Könnt ihr euch denken, warum

>>> l = []
>>> for i in range(4):
...   l.append({})
...
>>> l[0]['n'] = 3
>>> l

ganz anders ist?


Markus Demleitner

Copyright Notice