20. Dictionaries

In Sequenzen werden die Elemente immer durch einen ganzzahligen Index angesprochen. In Mappings (Abbildungen) kann der Index fast beliebig sein. Das Standard-Mapping in Python ist das dictionary (in anderen Sprachen heißt sowas auch hash oder associative array). Dictionaries werden in geschweiften Klammern notiert, auf die Elemente wird wieder mit eckigen Klammern zugegriffen.

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

Offenbar sind Dictionaries mutable – schon in diesem Beispiel verändern wir d, wovon ihr euch überzeugen könnt, wenn ihr euch zwischen der ersten und der zweiten Zeile d ausgeben lasst und euch klar macht, dass dem d selbst zwischendurch nicht zugewiesen wird.

Eine Anwendung bietet sich an: Wir wollen den Wert von Sätzen wie “eins plus eins” ausrechnen.

def compute(expr, langDict):
  """computes a pseudo-natural-language expression.

  The expression is passed in the string expr,
  langDict provides a mapping of single words to
  python values and operators.
  """
  pythonExpression = []
  for w in expr.split():
    pythonExpression.append(langDict[w])
  return eval("".join(pythonExpression))

Der komische String, der unter dem Funktionskopf steht, heißt Docstring. Wir werden in Kürze sehen, was es damit auf sich hat.

Die hier verwendete eingebaute Funktion eval gibt übrigens den Wert eines Python-Ausdrucks zurück:

>>> eval("5*4+10")
30

Ein Test mit d von oben:

>>> compute("eins plus zwei", d)
3

Es ist bei weitem nicht selbstverständlich, dass eine Sprache eine Funktion wie eval hat, die so einfach Ausdrücke aus dieser Sprache bewertet – C beispielsweise hat so ohne weiteres keine Einrichtung dieser Art.

Die Einfachheit, mit der sowas in Python geht, ist ein Nebeneffekt des Umstands, dass Python (mehr oder weniger) interpretiert wird. Auf der anderen Seite sollte man diesen Umstand auch nicht überbewerten – jede Programmiersprache, die mächtig genug ist (und das sind sie alle), erlaubt, dass eine Funktion wie eval in ihr geschrieben wird.

Sehr praktisch ist auch die Kombination von Dictionaries mit dem Prozentoperator für Strings. Wenn nämlich der zweite Operand ein Dictionary ist, muss zwischen Prozent und Formatcode in der Schablone in Klammern ein Schlüssel aus diesem Dictionary stehen. Folgendes sollte illustrieren, was da passiert:

>>> "%(prog)s ist %(num)d mal %(prop)s"%{
...     "prop": "toll",
...     "prog": "python",
...     "num": 7,}
'python ist 7 mal toll'

Übungen zu diesem Abschnitt

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

(1)

Wenn ihr “Formulare” ausfüllen müsst, ist der Prozentoperator mit einem Dictionary als zweitem Argument das Mittel der Wahl. Stellt euch vor, ihr bekommt die Ergebnisse einer Mensa-Umfrage in einer Liste von Dictionaries, von denen jedes etwa so aussieht:

d = {"kat": "Die Preise", "anteil": 95.7, "urteil": "zu hoch"}

Ihr sollt jetzt einen Formatstring angeben, so dass fmtStr%d etwas wie “Die Preise der Mensa wurde von 95.7% der Befragten als zu hoch eingeschätzt” ausgibt.

(2)

Macht ein Skript aus der Funktion compute (lest den zu berechnenden Ausdruck per raw_input) und erweitert das langDict, so dass ein paar mehr Operatoren und Zahlen verstanden werden.

(3)

Erweitert das Skript aus der letzten Aufgabe um eine weitere Funktion, die etwa für die Zahlen zwischen Null und Zwölf die Ergebnisse als Wort ausgibt (das könnt ihr über eine Liste oder ein Dictionary machen – was sind die Vor- und Nachteile dieser beiden Ansätze?). Was passiert, wenn eine Zahl ausgegeben werden soll, für die ihr kein Wort eingegeben habt?

(4)

Nicht alles kann Schlüssel in einem Dictionary sein. Im Groben taugt nur, was immutable ist. Denkt euch aus, wie ihr euch von dieser Behauptung überzeugen könnt.

(5)

Werte in Dictionaries können tatsächlich alles sein. Was wird etwa folgendes Skript ausgeben?

def f1(num):
  print num+1

def f2(num):
  print num -1

{'a':f1, 'b':f2}['a'](1)

Dateien zu diesem Abschnitt


Markus Demleitner

Copyright Notice