Seite 1 von 1

dursuchen von dictionary-listen

Verfasst: Dienstag 11. August 2009, 16:10
von 4bit
Hallihallo,

ich habe eine Liste von Dictionaries mit verschiedenen Eigenschaften und möchte einen Teil davon über boolsche Statements (in Werten von diesen Eigenschaften) auswählen können. Das Ergebnis der Suche ist aber nicht eine Liste mit allen Dictionaries, die mein Suchstatement erfüllen, sondern nur das Erste, das True zurückgibt. (in etwas wie EineListe.remove(einWert) nur das erste Auftreten von einWert löschen und mögliche zweite drin lassen).

konkret:

Code: Alles auswählen

dictions = [
{"state": "on", "size":5, "colour":"blue", "connections":12},
{"state": "on", "size":4, "colour":"blue", "connections":7},
{"state": "on", "size":1, "colour":"green", "connections":11},
{"state": "off", "size":5, "colour":"red", "connections":3},
{"state": "off", "size":1, "colour":"green", "connections":9}]

dictions["state"=="on" and "connections"<=11]
>>> {'connections': 12, 'state': 'on', 'colour': 'blue', 'size': 5}
und leider nicht die vollständige Liste (enthält 2 dictionaries).
Gibts da eine Möglichkeit das zu ändern? Ich kann natürlich eine eigene Function Select(liste, statement) schreiben, aber vielleicht gibts eine trickreichere Variante.

Grüße
4bit-

ps. merke grade, daß ich jetzt zur Fahrstunde muss, werde also wahrscheinlich erst morgen lesen und antworten können

Verfasst: Dienstag 11. August 2009, 16:27
von cofi
Der Code macht jedenfalls nicht das was du vermutest:

Code: Alles auswählen

In [46]: dictions = [
{"state": "off", "size":5, "colour":"blue", "connections":12},
{"state": "off", "size":4, "colour":"blue", "connections":7},
{"state": "off", "size":1, "colour":"green", "connections":11},
{"state": "off", "size":5, "colour":"red", "connections":3},
{"state": "off", "size":1, "colour":"green", "connections":9}]

In [52]: dictions["state"=="on" and "connections"<=11]
Out[52]: {'colour': 'blue', 'connections': 12, 'size': 5, 'state': 'off'}
Ich versuche selbst grad rauszufinden warum das funktioniert ...

Code: Alles auswählen

[dict_ for dict_ in dictions if dict_['state'] == 'on' and dict_['connections'] <= 11]
Edit: Es passiert wohl eine implizite Umwandlung in eine Ganzzahl, weil die Liste einen Index erwartet.

Code: Alles auswählen

In [61]: int("state"=="on" and "connections"<=11)
Out[61]: 0
Deshalb gibt dir dein Code auch immer das erste Element zurueck ;)

Verfasst: Mittwoch 12. August 2009, 08:46
von snafu
Nochmal zur Verdeutlichung: Das, was du als Schlüsselwert eingibst, sucht nicht nach allen Dictionarys, wo der "state" "on" ist. Python wertet dies "nur" als einen Vergleich:

Code: Alles auswählen

>>> "state"=="on" and "connections"<=11
False
False repräsentiert 0 und somit wird `dictions[0]` ausgegeben.

Dazu die Doku:
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int [...]

Verfasst: Mittwoch 12. August 2009, 09:56
von sma
4bit, du suchst eine List-Comprehension `[element for element in elements if condition(element)]`. Damit könntest du kompakt deine Liste filtern und eine neue Liste erzeugen, in der nur die Elemente enthalten sind, auf die dein Test zutrifft.

Stefan

Verfasst: Mittwoch 12. August 2009, 10:44
von snafu
Liegt das Verhalten des Dictionarys vielleicht daran:

Code: Alles auswählen

>>> True.real
1
>>> False.real
0
Dazu die Doku an entsprechender Stelle:
Complex numbers have a real and imaginary part, which are each implemented using double in C. To extract these parts from a complex number z, use z.real and z.imag.
Also greift Python intern auf diesen Wert zurück und erkennt es somit als "normale" 1 bzw. 0?

Verfasst: Mittwoch 12. August 2009, 10:51
von Trundle
@snafu: Du hast dir doch selber schon die Antwort gegeben, woran es liegt: `bool` erbt von `int`. Das ist alles. Keine Magie, nichts.

Verfasst: Mittwoch 12. August 2009, 12:11
von 4bit
@cofi: stimmt, wie blöd. War mir garnicht aufgefallen.

@sma: ah, wußte nicht, daß man da eine if Bedingung dranhängen kann. Super, danke.