basics michael poeltl © 2011-2013

Arbeiten mit dictionaries

Einleitung

dictionaries werden in anderen Programmiersprachen oft auch als assoziative arrays bezeichnet und gehören zu den map-datatypes in python (sind also KEINE Sequenzen und KEINE Mengen!).

Dictionaries - kurz dict, werden durch {} gekennzeichnet. Aber Vorsicht - auch set-Objekte sind seit Neuestem von geschwungenen Klammern (curly braces) eingeschlossen - man muss also mittlerweile schon genauer hinschauen!
Dictionaries sind mutaeble objects, und ist ein UNGEORDNETER Datentyp - es kommt NICHT auf eine bestimmte Reihenfolge an (daher keine Sequenz), und daher kann ein dict-Objekt auch nicht sortirt werden. Der python-Interpreter ordnet sich die Objekte so, wie es arbeitsspeichertechnisch am optimalsten zu sein scheint.

In dict haben wir key-value-Paare;
dabei muss der key ein immuteable/hashable-Object sein (eine Liste kann kein key sein, ein dict auch nicht)

leeres dict

>>> dd = dict()
>>> d = {}
>>> d['vorname'] = 'nico'
>>> d['nachname'] = 'mcguire'
>>> print (d)
{'nachname': 'mcguire', 'vorname': 'nico'}
>>> print (d['nachname'])
mcguire
>>>

oder man baut sich das dict so:

>>> inhalt = [('eins', 1), ('zwei', 2), ('drei', 3)]
>>> DD = dict(inhalt)
>>> print (DD)
{'drei': 3, 'eins': 1, 'zwei': 2}
>>>

oder einfach so

>>> a = dict(vorname='matt', nachname='sarang')
>>> a
{'nachname': 'sarang', 'vorname': 'matt'}
>>>

Man kann durch ein dict durchiterieren:
for i in <dict>
dabei iteriert man eigentlich durch die keys des dict.

>>> for i in d:
...     print (i)
... 
nachname
vorname
>>> for i in d:
...     print ('{}: {}'.format(i, d[i]))
... 
nachname: mcguire
vorname: nico
>>>

Ein großer Vorteil gegenüber Listen ist folgender:

>>> dd[0] = 'zero'
>>> dd[20] = 'twenty'
>>> dd[100] = 'hundred'
>>> print (dd[20])
twenty
>>> print (dd.keys())
dict_keys([0, 100, 20])
>>> print (dd.values())
dict_values(['zero', 'hundred', 'twenty'])
>>> print (type(dd.values()))
<class 'dict_values'>

Man kann ein dict-objekt zwar nicht sortieren, aber, man kann sie dennoch der sorted()-Funktion übergeben.
sorted() gibt die keys des dict sortiert als Listenobjekt zurück!

>>> D = {'zwei':2,'eins':1,'aa':'2a'}
>>> lD = sorted(D)
>>> print (lD)
['aa', 'eins', 'zwei']
>>>

Aber wieder Vorsicht! keys müssen vom selben Typ sein!

>>> D = {1:'eins','zwei':2,'eins':1}
>>> lD = sorted(D)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() < int()
>>>

Abfrage:
ist key xyz in dict? (True/False)

>>> 'sarang' in a
False
>>> 'nachname' in a
True
>>>

Zum Bau von dict-Objekten noch ein paar Beispiele von Michael Weigend aus Python Ge-Packt

>>> d = {('Fahrzeug', 'klein'):'Rollstuhl',
...      ('Fahrzeug', 'gross'):'bus',
...      ('Tier', 'klein'):'Maus',
...      ('Tier', 'gross'):'Elefant'}
>>> d[('Tier', 'klein')]
'Maus'
>>> deutsch={
...          'key':('Schluessel', 'Taste'),
...          'slice':('Scheibe', 'Schnitte', 'Stueck'),
...          'value':['wert']
...         }
>>> beatles = {}
>>> beatles = {}
>>> a = beatles
>>> a['drums'] = 'Ringo'
>>> a['bass'] = 'Paul'
>>> a['voice'] = 'John'
>>> a['guitar'] = 'George'
>>> beatles
{'guitar': 'George', 'voice': 'John', 'bass': 'Paul', 'drums': 'Ringo'}
>>> d.clear()
>>> for i in range(1,11):
...   d[i] = 'zahl '+str(i)
...
>>> d
{1: 'zahl 1', 2: 'zahl 2', 3: 'zahl 3', 4: 'zahl 4', 5: 'zahl 5',
6: 'zahl 6', 7: 'zahl 7', 8: 'zahl 8', 9: 'zahl 9', 10: 'zahl 10'}
>>> vornamen = ['michael','werner','wick','markus']
>>> freunde = dict()
>>> for name in vornamen:
...     freunde[name] = [None]*4
...
>>> print (freunde)
{'markus': [None, None, None, None], 'wick': [None, None, None, None], 'werner': [None, None, None, None], 'michael': [None, None, None, None]}
>>> NAME, ALTER, PLZ, HOBBY = range(4)
>>> freunde['michael'][NAME]={'vorname':'Michael','nachname':'Poeltl'}
>>> freunde['michael'][ALTER]=44
>>> freunde['michael'][HOBBY]='Schach'
>>> freunde['michael'][PLZ] = '1210'
>>> print (freunde['michael'])
[{'nachname': 'Poeltl', 'vorname': 'Michael'}, 44, '1210', 'Schach']
print (freunde['michael'][ALTER])
44
>>>

Methoden an dict-Objekten

>>> print (d.keys())
dict_keys(['nachname', 'vorname'])
>>> print (d.values())
dict_values(['mcguire', 'nico'])
>>> print (type(d.keys()))
<class 'dict_keys'>
>>>

Du kannst Dir wieder einfach key-value-Paare als tuple ausgeben lassen

>>> for paar in a.items():
...     print (paar)
...
('nachname', 'sarang')
('vorname', 'matt')
>>>

setdefauult()

Hier will man sich den Wert eines keys ausgeben lassen, und für den Fall, dass es den key noch nicht gibt, wird ein default-Wert gesetzt.

>>> a.setdefault('gesicht', 'oval')
'oval'
>>> print (a['gesicht'])
oval
>>> gesichtsform = a.setdefault('gesicht','rund')
>>> print (gesichtsform)
oval
>>>

pop()

popped wieder den value eines keys bei gleichzeitiger Entfernung des kv-Paares

>>> a['haare'] = 'kurs'
>>> a['haarfarbe'] = 'schwarz'
>>> a['groesse'] = '180cm'
>>>

Da dict UNGEORDNET ist, kann pop() nicht einfach der Wert des letzten items 'rauspoppen.

>>> a.pop()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 TypeError: pop expected at least 1 arguments, got 0
>>>

Es muss dem also der key bekanntgegeben werden

>>> haare_sarang = a.pop('haare')
>>> print (haare_sarang)
kurs
>>> print (a)
{'haarfarbe': 'schwarz', 'groesse': '180cm', 'gesicht': 'oval', 'nachname': 'sarang', 'vorname': 'matt'}
>>>

popitem()

Hier ist es so, dass das erstbeste kv-Paar zum Auffangen oder Ausgeben herausgepoppt wird.

>>> print (a.popitem())
('haarfarbe', 'schwarz')
>>> print (a.popitem())
('groesse', '180cm')
>>>

copy()

Macht wieder eine flache Kopie eines dict-Objekts

>>> d1 = {'eins':1,'zwei':2,'drei':3,'vier':4}
>>> d2 = d1
>>> d3 = d1.copy()
>>> d2.pop('zwei')
2
>>> print (d1)
{'drei': 3, 'vier': 4, 'eins': 1}
>>> print (d3)
{'drei': 3, 'vier': 4, 'eins': 1, 'zwei': 2}
>>>

update()

Wir können das dict-Objekt, auf das d1 und d2 zeigen, mittels der update-Methode an d3 anpassen.

>>> d1.update(d3)
>>> print (d1)
{'drei': 3, 'eins': 1, 'zwei': 2, 'vier': 4}
>>>

d1 wurde um jene items, die d3 mehr hatte als d1 upgedated.

clear()

leert ein dict-Objekt

>>> d1.clear()
>>> print (d1)
{}
>>>

get()

Gibt den Wert zu key aus, wenn key im dict-Objekt vorhanden ist; ist key nicht im dict-Objekt, dann gibt die Methode None zurück.
Alternativ kann man einen default-Wert ausgeben lassen (nicht so wie bei setdefault).

>>> print (a.get('vorname'))
matt
>>> print (a.get('haare'))
None
>>> print (a.get('haare','keine Angabe'))
keine Angabe
>>>

dict comprehension

list comprehensions kennen wir schon - nun gibt es das auch für dictionaries. Da ein dictionary 'rauskommen soll, muss man vor der for-Schleife ein kv-Pair angeben. Eingeschlossen wird die comprehension mit curly braces.

>>> d = { zeichen:ord(zeichen) for zeichen in 'michael' }
>>> print (d)
{'a': 97, 'c': 99, 'e': 101, 'i': 105, 'h': 104, 'm': 109, 'l': 108}
>>>

dict comprehension gibt es erst seit python-3.0, und ist eine tolle Erweiterung unserer Möglichkeiten.

Abschließend noch ein Hinweis an zwei Nahverwandte, die du dir beizeiten 'ma lansehen kannst:
im Modul collections gibt es defaultdict und OrderedDict.


Hier geht es zum Seitenanfang und da geht es zur python-Startseite