"Bug" im Datentyp dict?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
pSy
User
Beiträge: 44
Registriert: Montag 4. Oktober 2004, 17:58
Kontaktdaten:

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?
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

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.
Gruß, Harry
XT@ngel
User
Beiträge: 255
Registriert: Dienstag 6. August 2002, 14:36
Kontaktdaten:

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]
pSy
User
Beiträge: 44
Registriert: Montag 4. Oktober 2004, 17:58
Kontaktdaten:

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...
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Wie sieht denn diese Suchfunktion aus?
Gruß, Harry
pSy
User
Beiträge: 44
Registriert: Montag 4. Oktober 2004, 17:58
Kontaktdaten:

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]
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

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.
Gruß, Harry
pSy
User
Beiträge: 44
Registriert: Montag 4. Oktober 2004, 17:58
Kontaktdaten:

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.
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Aber dabei ist doch die Reihenfolge der Suchstrings unwichtig!
Du durchsuchts ja sowieso alle keys in abDict.
Gruß, Harry
pSy
User
Beiträge: 44
Registriert: Montag 4. Oktober 2004, 17:58
Kontaktdaten:

genau das habe ich auch gedacht... aber da ergebniss ist trotzdem verdreht, falls ich bei abDict keine Integer verwende...
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

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.
Gruß, Harry
pSy
User
Beiträge: 44
Registriert: Montag 4. Oktober 2004, 17:58
Kontaktdaten:

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.
Zuletzt geändert von pSy am Donnerstag 20. Januar 2005, 13:34, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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()
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

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
[code]#!/usr/bin/env python
import this[/code]
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

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: .
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Und ins bestof ;)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten