mit if-Anweisung auf key eines dict zugreifen

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
raibel
User
Beiträge: 30
Registriert: Mittwoch 15. November 2006, 22:03

Hallo zusammen!

Ich hab ein Verständnisproblem und bitte um eure Hilfe.

Ich habe dict-keys mit drei Zeichen und möchte auf das mittlere Zeichen zugreifen, um dessen Wert weiterbearbeiten zu können.

Beispiel:

Code: Alles auswählen

d = {(0, 2, 0):200, (4, 1, 0):100, (4, 4, 0):400, (4, 3, 0):300}

x = d.items()
x.sort()

for key, value in x: #d.items():  ____sortiert

    if key[1] == 1: 
        a = value
    if key[1] == 2: 
        b = value
    if key[1] == 3: 
        c = value
    if key[1] == 4: 
        d = value
        print a, b, c, d
sortiert => funktioniert!

Code: Alles auswählen

d = {(0, 2, 0):200, (4, 1, 0):100, (4, 4, 0):400, (4, 3, 0):300}

#x = d.items()
#x.sort()

for key, value in d.items(): # ____ nicht sortiert!

    if key[1] ==1: 
        a = value
    if key[1] == 2: 
        b = value
    if key[1] == 3: 
        c = value
    if key[1] == 4: 
        d = value
        print a, b, c, d
nicht sortiert => funktioniert nicht!
Meldung:

Code: Alles auswählen

The debugged program raised the exception NameError
"name 'a' is not defined"
File: /home/mund/222.py, Line: 16
Wenn ich beim dritten Schlüssel (Wert = 400) das erste Zeichen auf 0 setze, geht es wieder!!??

In dem Zusammenhang. Es gibt bestimmt auch eine bessere Lösung, als diese if-Kaskade.

Warum ist das so, und/oder wie kann ich es anders machen?

Grüße

rai
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Irgendwie macht das alles so keinen Sinn für mich. Es liegt nicht am sortieren, sondern an der generellen Programmlogik...

Im zweiten Beispiel kommt es zu dem Fehler, weil a halt nicht definiert ist, weil die if Abfrage nicht eingetroffen ist...

Was soll denn da überhaupt raus kommen? Was sind das für Daten, wo kommen die her?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Ich finde die Programmlogik auch merkwürdig. Insbesondere wenn vorher sortiert wird, sind die ``if``-Abfragen doch unnötig, dann kann man die Werte doch einfach `a` bis `d` zuweisen.

Code: Alles auswählen

In [26]: D = {(0, 2, 0): 200, (4, 1, 0): 100, (4, 4, 0): 400, (4, 3, 0): 300}

In [27]: a, b, c, d = (y[1] for y in sorted(D.items(), key=lambda x: x[0][1]))

In [28]: print a, b, c, d
100 200 300 400
raibel
User
Beiträge: 30
Registriert: Mittwoch 15. November 2006, 22:03

Hallo!

@BlackJack

sehe ich das richtig, das das nur bei vier Schlüssel-Wert-Paaren funktioniert?

---
Am besten versuch ich mal, das anders zu formulieren.

Ich habe eine variable Anzahl von Schlüssel-Wert-Paaren, die so aussehen:

Code: Alles auswählen

{(8,2,3) : value, (4,1,2) : value, .u..s..w..} 
Der Schlüssel besteht aus drei Zahlen. Die mittlere Zahl aus dem Schlüssel ist immer entweder eine 1, oder 2, oder 3, oder 4

Ich suche eine Funktion, die mir zu der mittleren Zahl den Wert des Schlüssels liefert. Diese Werte möchte ich dann getrennt weiterbearbeiten.

Wie im Beispiel oben

Code: Alles auswählen

for key, value in x: #d.items():  ____sortiert

    if key[1] == 1:
        a = value
    if key[1] == 2:
        b = value
    if key[1] == 3:
        c = value
    if key[1] == 4:
        d = value
        print a, b, c, d
Das funktioniert auch mit dem sortierten dict und der if-Kaskade.
Aber das dict muss nicht sortiert sein und ich habe bei dieser if-Abfolge das Gefühl, das das so nicht richtig ist.

Ich finde einfach keine andere Lösung!

@ jens
Es liegt nicht am sortieren, sondern an der generellen Programmlogik...
Vielleicht ist es jetzt besser nachzuvollziehen. Es gibt da bestimmt eine profesionellere Lösung.

Grüße
rai
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

raibel hat geschrieben:

Code: Alles auswählen

for key, value in x: #d.items():  ____sortiert

    if key[1] == 1:
        a = value
    if key[1] == 2:
        b = value
    if key[1] == 3:
        c = value
    if key[1] == 4:
        d = value
        print a, b, c, d
Dir ist da offenbar was entgangen. Schaue dir den Code nochmal genau an und überlege, was da wann unter welchen Bedinungen passiert.

Das `print`-Statement (das übrigens nur bei Betreten der letzten `if`-Abfrage ausgeführt wird) soll alle vier Objekte ausgeben. Das kann es aber nur, wenn *alle* vier Bedingungen erfüllt worden sind. Das wiederum kann aber nie passieren, da `key[1]` nur (wenn überhaupt) einen der Vergleichswerte annehmen kann, aber nie alle vier. Entsprechend kann `value` auch nur an einen der vier Namen `a`, `b`, `c` oder `d` gebunden werden.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Y0Gi hat geschrieben:
raibel hat geschrieben:

Code: Alles auswählen

for key, value in x: #d.items():  ____sortiert

    if key[1] == 1:
        a = value
    if key[1] == 2:
        b = value
    if key[1] == 3:
        c = value
    if key[1] == 4:
        d = value
        print a, b, c, d
Dir ist da offenbar was entgangen. Schaue dir den Code nochmal genau an und überlege, was da wann unter welchen Bedinungen passiert.

Das `print`-Statement (das übrigens nur bei Betreten der letzten `if`-Abfrage ausgeführt wird) soll alle vier Objekte ausgeben. Das kann es aber nur, wenn *alle* vier Bedingungen erfüllt worden sind. Das wiederum kann aber nie passieren, da `key[1]` nur (wenn überhaupt) einen der Vergleichswerte annehmen kann, aber nie alle vier. Entsprechend kann `value` auch nur an einen der vier Namen `a`, `b`, `c` oder `d` gebunden werden.
Doch, kann es, da es in einer Schleife steht und key sich somit ändert. a, b und c müssen aber vor d gesetzt werden. Deshalb "funktioniert" es u.a., wenn nach key[1] sortiert wurde. Ob dies Verhalten aber so wirklich erwünscht ist?
MfG
HWK
raibel
User
Beiträge: 30
Registriert: Mittwoch 15. November 2006, 22:03

Hallo,

ja, deshalb funktioniert es auch nur, wenn das dict sortiert ist. richtig?

In meinem letzten post steht doch, das ich nach einer besseren Lösung suche, weil mir das so nicht richtig vorkommt!

Grüße

rai
raibel
User
Beiträge: 30
Registriert: Mittwoch 15. November 2006, 22:03

HWK war schneller.

Mein letzter post war eine Antwort auf YOGI's Post

Grüße

rai
OldBoy
User
Beiträge: 41
Registriert: Samstag 12. Januar 2008, 20:39

Hallo miteinander,

wie wär's hiermit:

- funktioniert für beliebig viele Einträge in d
- 2. Element des Schlüssel muss ein Integer und größer 0 sein
- Ergebnis ist sortiert

Code: Alles auswählen

d = {(0, 2, 0):200, (4, 1, 0):100, (4, 4, 0):400, (4, 3, 0):300}

result1 = [None]*(len(d)+1)

print 'Originaldaten, unsortiert'
for key, value in d.iteritems():
    print key, value
    result1[key[1]] = value

print 'Ergebnis, aufsteigend nach Index'
for i,x in enumerate(result1):
    print i, x

result2 = [x for x in result1 if x]
print 'Ergebnis als list'
print result2
Gruss

OldBoy
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Verdammt, da habe ich doch glatt die Schleife übersehen X-(
raibel
User
Beiträge: 30
Registriert: Mittwoch 15. November 2006, 22:03

Hallo,

@ OldBoy

irgendwie versteh ich das nicht. Die Werte bekomme ich doch auch, wenn ich direkt über dict iteriere. Oder habe ich was übersehen? Und wie komme ich an die einzelnen Werte?
---
Hier mal die Variante mit if und einem Auszug aus meinem dict.

Code: Alles auswählen

d = {(28, 4, 1): '', (21, 3, 1): '', (14, 2, 1): '', (5, 2, 1): '', (23, 3, 1): '', (14, 1, 1): '', (7, 1, 1): '',
     (7, 2, 1): '', (32, 3, 1): '', (7, 4, 1): '', (9, 1, 1): '', (25, 4, 1): '', (25, 2, 1): '', (18, 4, 1): '',
     (27, 1, 1): '', (18, 3, 1): '', (27, 2, 1): '', (20, 3, 1): '', (4, 1, 1): '', (22, 4, 1): '', (29, 3, 1): '',
     (22, 2, 1): '', (13, 2, 1): '', (31, 3, 1): '', (22, 1, 1): '', (24, 4, 1): '', (6, 3, 1): '', (8, 2, 1): '',
     (15, 2, 1): '', (24, 1, 1): '', (17, 1, 1): '', (16, 4, 1): '', (3, 3, 1): '17', (3, 4, 1): '15', (15, 1, 1): '',
     (26, 4, 1): '', (26, 3, 1): '', (28, 3, 1): '', (12, 1, 1): '', (5, 1, 1): '', (32, 4, 1): '', (30, 2, 1): '',
     (21, 2, 1): '', (5, 4, 1): '', (23, 1, 1): '', (14, 3, 1): '', (16, 2, 1): '', (23, 2, 1): '', (23, 4, 1): '',
     (25, 1, 1): '', (9, 3, 1): '', (2, 2, 1): '45', (11, 3, 1): '', (2, 1, 1): '10', (11, 4, 1): '', (4, 2, 1): '',
     (32, 1, 1): '', (4, 4, 1): '', (20, 1, 1): '', (13, 1, 1): '', (29, 2, 1): '', (13, 4, 1): '', (31, 1, 1): '',
     (22, 3, 1): '', (24, 2, 1): '', (31, 2, 1): '', (8, 3, 1): '', (16, 1, 1): '', (15, 4, 1): '', (31, 4, 1): '',
     (17, 3, 1): '', (10, 2, 1): '', (19, 3, 1): '', (10, 1, 1): '', (3, 1, 1): '15', (19, 4, 1): '', (12, 2, 1): '',
     (3, 2, 1): '45', (12, 4, 1): '', (28, 1, 1): '', (21, 1, 1): '', (5, 3, 1): '', (7, 3, 1): '', (21, 4, 1): '',
     (30, 3, 1): '', (32, 2, 1): '', (30, 4, 1): '', (9, 4, 1): '', (25, 3, 1): '', (18, 2, 1): '', (9, 2, 1): '',
     (27, 3, 1): '', (18, 1, 1): '', (11, 1, 1): '', (2, 4, 1): '15', (20, 2, 1): '', (11, 2, 1): '', (30, 1, 1): '',
     (4, 3, 1): '', (6, 4, 1): '', (2, 3, 1): '12', (20, 4, 1): '', (29, 1, 1): '', (13, 3, 1): '', (6, 2, 1): '',
     (15, 3, 1): '', (6, 1, 1): '', (8, 4, 1): '', (29, 4, 1): '', (24, 3, 1): '', (8, 1, 1): '', (17, 4, 1): '',
     (16, 3, 1): '', (27, 4, 1): '', (26, 2, 1): '', (17, 2, 1): '', (10, 4, 1): '', (26, 1, 1): '', (19, 1, 1): '',
     (10, 3, 1): '', (28, 2, 1): '', (19, 2, 1): '', (12, 3, 1): '', (14, 4, 1): ''}

x = d.items()
x.sort()

list = []
for key, value in x:

    if key[1] == 1:
        a = int(value or 0)
    if key[1] == 2:
        b = int(value or 0)
    if key[1] == 3:
        c = int(value or 0)
    if key[1] == 4:
        d = int(value or 0)
        x = c - a
        y = d - b
        z = x * 60 + y
        list.append(z)
s = sum(list)
print s
So möchte ich halt mit den Werten rechnen. In diesem Fall 10:45 - 12:15 und 15:45 - 17:15 = 180 Min. Das funktioniert.
Nur muss das dict halt sortiert und die Schlüssel ohne Unterbrechung durchnummeriert sein.
Soll ich das so lassen? Wie gesagt, es kommt mir nicht ganz koscher vor.

Grüße
rai
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Also...sind das Zeiten?
Ist dir das Modul datetime zu...einfach und deshalb willst du das Rad neu erfinden?
raibel
User
Beiträge: 30
Registriert: Mittwoch 15. November 2006, 22:03

Hallo,

@ audax

bitte ein Beispiel, wie ich mit datetime an den Wert des Schlüssels key[1] == 3 komme und diesen Wert von dem Wert mit dem Schlüssel key[1] == 1
abziehe.

Ich habe doch schon die Minuten und die Ausgabe mache ich dann über divmod!

Wenn mit datetime eine elegantere Lösung möglich ist, gerne.


Grüße

rai
OldBoy
User
Beiträge: 41
Registriert: Samstag 12. Januar 2008, 20:39

Hallo,

@raibel

wie wär's, wenn du jetzt erst mal versuchst, dein Problem bzw. deine Aufgabenstellung genau zu beschreiben. Deine Datenstruktur im letzten Post ist etwas anders als im ersten Post und jetzt stecken plötzlich irgendwo Zeitangaben drin.

Im Augenblick kenne ich das Problem nicht, habe zwei Teillösung von dir, die nicht funktionieren und soll helfen?

Die Fragen, die ich mir so spontan stelle:
- was hast du am Anfang für Daten
- wie kommen die Daten ins Programm
- was für Ergebnisse möchtest du aus diesen Daten ermitteln

Gruss

OldBoy
raibel
User
Beiträge: 30
Registriert: Mittwoch 15. November 2006, 22:03

Hallo,

@ OldBoy

Der Code aus meinem post um 17:12 funktioniert! Hab ihn grad noch mal
laufen lassen.

Das Programm läuft mit dem o.g. Code!

Eigentlich möchte ich nur wissen, ob es eine Möglichkeit gibt, das Berechnen der Werte ohne if-Kaskade und/oder ohne sortiertem dict hinzubekommen.

Aber ich glaube, ich geb es langsam auf. Eigentlich wiederhole ich mich nur ständig. ':?'

Grüße ':)'

rai
Antworten