Seite 1 von 1

"Bug" im Datentyp dict?

Verfasst: Donnerstag 20. Januar 2005, 10:39
von pSy
Ich habe mal bemerkt das es Probleme mit einem dict gibt.

Beispiel:

Code: Alles auswählen

dct = {1: 'No1', 2: 'No2', 3: 'No3'}
for x in dct: print str(x)+':\t'+dct[x]
Ergibt wie erwartet:
1: No1
2: No2
3: No3

Code: Alles auswählen

dct = {'1': 'No1', '2': 'No2', '3': 'No3'}
for x in dct: print str(x)+':\t'+dct[x]
Ergibt aber nicht wie erwartet:
1: No1
3: No3
2: No2
Woran liegts?

re:

Verfasst: Donnerstag 20. Januar 2005, 11:31
von HarryH
Hallo pSy,


Das ist kein Bug! Wenn du ein neues Dict anlegst oder Daten zu einem bereits vorhandenen Dict hinzufügst, kannst du die Reihenfolge der Keys nicht beeinflussen.

Verfasst: Donnerstag 20. Januar 2005, 11:41
von XT@ngel
bei deinem zweiten Beispiel kannst du str() weglassen:

Code: Alles auswählen

dct = {'1': 'No1', '2': 'No2', '3': 'No3'}
for x in dct: print x +':\t'+dct[x] 
da die Keys eh schon strings sind.

MfG
Andreas[/code]

Verfasst: Donnerstag 20. Januar 2005, 11:45
von pSy
ja... klar.. hab das nur auf die schnelle von oben kopiert...

@HarryH: aber wieso ließt er es dann falsch aus? wenn ich eine suchfunktion baue die in so einem dict einen bestimmten eintrag finden soll, findet sie eintrag drei, wenn es eintrag zwei sein sollte und umgedreht. benutze ich keine strings als bezeichner, funktioniert die suchfunktion wieder einwandfrei...

re:

Verfasst: Donnerstag 20. Januar 2005, 11:49
von HarryH
Wie sieht denn diese Suchfunktion aus?

Re: re:

Verfasst: Donnerstag 20. Januar 2005, 12:00
von pSy
HarryH hat geschrieben:Wie sieht denn diese Suchfunktion aus?
...*kram*

das müsste sie sein:

Code: Alles auswählen

z = 0
for entry in abDict:
   z = 0
   for x in abDict[entry]:
      if search in x and z == 0:
         z = 1
         print str(entry)+':'
         line = abDict[entry]
         print line[1]+' '+line[0]
         print line[2]+' '+line[3]
         print line[4]+' '+line[5]
         for y in range(6,len(line)):
            if len(line[y]) > 0: print line[y]

re:

Verfasst: Donnerstag 20. Januar 2005, 12:10
von HarryH
Mir fehlt noch abDict und search, da ich die Funktion sonst nicht prüfen kann.
Dazu noch eine Frage. Was hast du vor? Vielleicht gibt es einen anderen Lösungsweg.

Verfasst: Donnerstag 20. Januar 2005, 12:25
von pSy
search ist ein String der den Suchstring darstellt und abDict ist ein dict vergleichbar mit dem Beispiel... allerdings verwendet es inzwischen Strings als Bezeichner.

Also zB:
search = 'mann'
abDict = {'1': ['Hampelmann','Neue Straße 5','Musterstadt'], '2': ['Dieter','Alte Straße 7','Musterstadt'], '3': ['Der Andere','Andere Straße 2','Musterstadt']

Das Dict ist der Inhalt eines "Adressbuchs" was mit dieser Funktion durchsucht werden soll.

re:

Verfasst: Donnerstag 20. Januar 2005, 12:50
von HarryH
Aber dabei ist doch die Reihenfolge der Suchstrings unwichtig!
Du durchsuchts ja sowieso alle keys in abDict.

Verfasst: Donnerstag 20. Januar 2005, 13:01
von pSy
genau das habe ich auch gedacht... aber da ergebniss ist trotzdem verdreht, falls ich bei abDict keine Integer verwende...

re:

Verfasst: Donnerstag 20. Januar 2005, 13:24
von HarryH
Ich glaube ich habe das missverstanden.

Die erste for-Schleife läuft über die keys in abDict. Deswegen wird die Reihenfolge der gefunden Suchstellen durch die Reihenfolge der keys bestimmt. Und die ist eben in einem Dictionary nicht beeinflußbar. Sie wird durch Python intern festgelegt. Sie entspricht nicht unbedingt der Reihenfolge nach der du die keys angelegt hast und auch nicht irgendeiner alphabetischen Reihenfolge.
Somit erhälst du auch verschiedene Ausgaben.

Du könntest aber bevor die Schleife beginnt die keys sortieren und dann über die sortierten keys iterieren.
Beispiel:

Code: Alles auswählen

search = 'Straße'
abDict = {  "1": ['Hampelmann','Neue Straße 5','Musterstadt'],
            "2": ['Dieter','Alte Straße 7','Musterstadt'],
            "3": ['Der Andere','Andere Straße 2','Musterstadt'],
            "4": ['Hampelmann 2','Andere Straße 2','Musterstadt'],
         }

keys = abDict.keys()
keys.sort()

for entry in keys:
    for x in abDict[entry]:
       if search in x:
            print str(entry)+':'

            line = abDict[entry]
            try:
                print line[1]+' '+line[0]
                print line[2]+' '+line[3]
                print line[4]+' '+line[5]
            except:
                pass
            for y in range(6,len(line)):
                if len(line[y]) > 0: print line[y]
            break
Edit (Leonidas): Code in Python-Tags gesetzt.

Verfasst: Donnerstag 20. Januar 2005, 13:33
von pSy
oder eben nicht Strings wie '1' oder '2' zum iterieren verwenden, sondern einfache Integer... das klappt einwandfrei. Allerdings funktioniert das inzwischen eh anders, da ich die Reihenfolge sowieso sortiere...
Mir ging es primär nur um dieses seltsame Verhalten.

Verfasst: Donnerstag 20. Januar 2005, 13:34
von Leonidas
Ich weiß zwar nicht ob dich die findme() Funkton in meiner Lösung interessiert, aber so wie ich das verstehe suchst du einfach nur einen Eintrag in abDict der den String search enthält, oder? Auf jeden Fall, habe ich es leider nicht geschafft die Funktion psy() auf die Schnelle zum laufen zu bekommen.

Code: Alles auswählen

#!/usr/bin/env python
# -*- encoding: latin-1 -*-
search = 'mann'

abDict = {'1': [u'Hampelmann',u'Neue Straße 5',u'Musterstadt'],
    '2': [u'Dieter',u'Alte Straße 7',u'Musterstadt'],
    '3': [u'Der Andere',u'Andere Straße 2',u'Musterstadt']}
    
def psy():
    z = 0 
    for entry in abDict:
        z = 0
        for x in abDict[entry]:
            if search in x and z == 0:
                z = 1
                print str(entry)+':'
                line = abDict[entry]
                print line[1]+' '+line[0]
                print line[2]+' '+line[3]
                print line[4]+' '+line[5]
                for y in range(6,len(line)):
                    if len(line[y]) > 0: print line[y]

def findme():
    for entry in abDict:
        for field in abDict[entry]:
            print field
            if search in field:
                return entry

#psy()
print findme()

Verfasst: Donnerstag 20. Januar 2005, 14:26
von Dookie
Hi pSy,

das deiner Meinung nach seltsame Verhalten von Dictionaries, liegt an der Art, wie die Schlüssel/Werte-Paare gespeichert werden. Dies geschieht nicht in der Reihenfolge, wie sie in das Dictionary eingetragen werden, sondern die Reihenfolge ist scheinbar zufällig. Das hat durch den zugrundeliegenden Algorithmus den Vorteil, daß ein Eintrag anhand des Schlüssels sehr schnell gefunden wird.

Stichwort: Hashtable


Gruß

Dookie

Verfasst: Donnerstag 20. Januar 2005, 19:01
von Milan
Hi. Habs mir jetzt nicht komplett durchgelesen, aber wir hatte so was ähnliches shcon mal... rausgekommen ist ein neuer Datentyp: Lict als Kreuzung von Liste und Dictionary. Könnte vielleicht auch mit in die Codesnipetts aufgenommen werden :wink: .

Verfasst: Donnerstag 20. Januar 2005, 19:46
von Leonidas
Und ins bestof ;)