Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

dict filtern

5 views
Skip to first unread message

Philipp Kraus

unread,
Apr 14, 2013, 11:44:11 AM4/14/13
to
Hallo,

ich habe folgendes dict:
x = {

"data1" : {
"item 1" : {
"kind" : "a"
....
} ,

"item 2" : {
"kind" : "a"
....
},

"item 3" : {
"kind" : "b"
....
}
},
....
}


ich durchlaufe das dict so:

for key, value in x.iteritems() :
y = ?
if y :
do something with y


Ich m�chte an der Stelle ? pr�fen, ob sich innerhalb der Kindelemente
von value ein Feld
mit dem Typ "a" enth�lt, wenn dies der Fall ist, soll der if Zweig
ausgef�hrt werden. Ich w�rde
jetzt mit filter versuchen das zu l�sen und dann via if pr�fen, ob die
Liste leer ist. Geht das
vielleicht irgendwie kompakter z.B.

if any(value.items.child("kind") == "a")

Danke

Phil

Sebastian Bechtel

unread,
Apr 14, 2013, 12:01:04 PM4/14/13
to Philipp Kraus, pyth...@python.org
Am 14.04.2013 um 17:44 schrieb Philipp Kraus <philip...@flashpixx.de>:

> Hallo,
>
> ich habe folgendes dict:
> x = {
>
> "data1" : {
> "item 1" : {
> "kind" : "a"
> ....
> } ,
>
> "item 2" : {
> "kind" : "a"
> ....
> },
>
> "item 3" : {
> "kind" : "b"
> ....
> }
> },
> ....
> }
>
>
> ich durchlaufe das dict so:
>
> for key, value in x.iteritems() :
> y = ?
> if y :
> do something with y
>
>
> Ich möchte an der Stelle ? prüfen, ob sich innerhalb der Kindelemente von value ein Feld
> mit dem Typ "a" enthält, wenn dies der Fall ist, soll der if Zweig ausgeführt werden. Ich würde
> jetzt mit filter versuchen das zu lösen und dann via if prüfen, ob die Liste leer ist. Geht das
> vielleicht irgendwie kompakter z.B.
>
> if any(value.items.child("kind") == "a")
>
> Danke
>
> Phil
>
> _______________________________________________
> python-de maillist - pyth...@python.org
> http://mail.python.org/mailman/listinfo/python-de

Du kannst einfach drauf zugreifen und bei Misserfolg die Exception behandeln

Philipp Kraus

unread,
Apr 14, 2013, 12:52:18 PM4/14/13
to pyth...@python.org

Am 14.04.2013 um 18:01 schrieb Sebastian Bechtel:

> Am 14.04.2013 um 17:44 schrieb Philipp Kraus <philip...@flashpixx.de>:
>
>> Hallo,
>>
>> ich habe folgendes dict:
>> x = {
>>
>> "data1" : {
>> "item 1" : {
>> "kind" : "a"
>> ....
>> } ,
>>
>> "item 2" : {
>> "kind" : "a"
>> ....
>> },
>>
>> "item 3" : {
>> "kind" : "b"
>> ....
>> }
>> },
>> ....
>> }
>>
>>
>> ich durchlaufe das dict so:
>>
>> for key, value in x.iteritems() :
>> y = ?
>> if y :
>> do something with y
>>
>>
>> Ich möchte an der Stelle ? prüfen, ob sich innerhalb der Kindelemente von value ein Feld
>> mit dem Typ "a" enthält, wenn dies der Fall ist, soll der if Zweig ausgeführt werden. Ich würde
>> jetzt mit filter versuchen das zu lösen und dann via if prüfen, ob die Liste leer ist. Geht das
>> vielleicht irgendwie kompakter z.B.
>>
>> if any(value.items.child("kind") == "a")
>>
>> Danke
>>
>> Phil
>>
>> _______________________________________________
>> python-de maillist - pyth...@python.org
>> http://mail.python.org/mailman/listinfo/python-de
>
> Du kannst einfach drauf zugreifen und bei Misserfolg die Exception behandeln

Das geht hier nicht, denn ich muss auf die Existenz prüfen, nur wenn mind. ein Element vorhanden
ist, dann darf ich den if Zweig ausführen, wenn nicht, darf er gar nicht ausgeführt werden.
Im Grunde wäre die Frage "ist mindestens ein Element mit kind == a vorhanden, wenn ja, führe für jedes
Element mit kind == a aus, wenn nein, dann überspringe Ausführung".
Im Grunde entspricht kind einem Enum und anhand dessen muss die Verarbeitung unterschiedlich statt finden

Peter Otten

unread,
Apr 14, 2013, 1:40:11 PM4/14/13
to pyth...@starship.python.net
Philipp Kraus wrote:

> Hallo,
>
> ich habe folgendes dict:
> x = {
>
> "data1" : {
> "item 1" : {
> "kind" : "a"
> ....
> } ,
>
> "item 2" : {
> "kind" : "a"
> ....
> },
>
> "item 3" : {
> "kind" : "b"
> ....
> }
> },
> ....
> }
>
>
> ich durchlaufe das dict so:
>
> for key, value in x.iteritems() :
> y = ?
> if y :
> do something with y
>
>
> Ich möchte an der Stelle ? prüfen, ob sich innerhalb der Kindelemente
> von value ein Feld
> mit dem Typ "a" enthält, wenn dies der Fall ist, soll der if Zweig
> ausgeführt werden. Ich würde
> jetzt mit filter versuchen das zu lösen und dann via if prüfen, ob die
> Liste leer ist. Geht das
> vielleicht irgendwie kompakter z.B.
>
> if any(value.items.child("kind") == "a")

Ich werde aus deiner Problembeschreibung nicht ganz schlau. Wenn es sich bei
allen Werten um zweifach verschachtelte dicts handelt:

for key, outer in x.iteritems():
if any(inner.get("kind") == "a" for inner in outer.itervalues()):
...



Philipp Kraus

unread,
Apr 14, 2013, 1:59:04 PM4/14/13
to Peter Otten, pyth...@starship.python.net

Am 14.04.2013 um 19:40 schrieb Peter Otten:

> Philipp Kraus wrote:
>
>> Hallo,
>>
>> ich habe folgendes dict:
>> x = {
>>
>> "data1" : {
>> "item 1" : {
>> "kind" : "a"
>> ....
>> } ,
>>
>> "item 2" : {
>> "kind" : "a"
>> ....
>> },
>>
>> "item 3" : {
>> "kind" : "b"
>> ....
>> }
>> },
>> ....
>> }
>>
>>
>> ich durchlaufe das dict so:
>>
>> for key, value in x.iteritems() :
>> y = ?
>> if y :
>> do something with y
>>
>>
>> Ich möchte an der Stelle ? prüfen, ob sich innerhalb der Kindelemente
>> von value ein Feld
>> mit dem Typ "a" enthält, wenn dies der Fall ist, soll der if Zweig
>> ausgeführt werden. Ich würde
>> jetzt mit filter versuchen das zu lösen und dann via if prüfen, ob die
>> Liste leer ist. Geht das
>> vielleicht irgendwie kompakter z.B.
>>
>> if any(value.items.child("kind") == "a")
>
> Ich werde aus deiner Problembeschreibung nicht ganz schlau. Wenn es sich bei
> allen Werten um zweifach verschachtelte dicts handelt:
>
> for key, outer in x.iteritems():
> if any(inner.get("kind") == "a" for inner in outer.itervalues()):
> ...

Ich stehe aktuell auf dem Eintrag data1, also auf meiner äußeren
Schleife und nun will ich wissen, ob sich in meinen data1.values
ein Eintrag findet, der ein kind == a enthält, wenn ja möchte ich alle
diese Einträge haben und mit diesen etwas machen, in etwas so:

for k,v in x.iterateitems() :

list = []
for a,b in v.iterateitems() :
if b.has_key("kind") and b["kind"] == "a" :
list.append(dict(a,b))

if list :
do_something(list)


Peter Otten

unread,
Apr 14, 2013, 2:29:51 PM4/14/13
to pyth...@starship.python.net
Philipp Kraus wrote:

> Ich stehe aktuell auf dem Eintrag data1, also auf meiner äußeren
> Schleife und nun will ich wissen, ob sich in meinen data1.values
> ein Eintrag findet, der ein kind == a enthält, wenn ja möchte ich alle
> diese Einträge haben und mit diesen etwas machen, in etwas so:
>
> for k,v in x.iterateitems() :
>
> list = []
> for a,b in v.iterateitems() :
> if b.has_key("kind") and b["kind"] == "a" :
> list.append(dict(a,b))
>
> if list :
> do_something(list)

Das ist äquivalent zu

for k, v in x.iteritems():
items = [{a: b} for a, b in v.iteritems() if b.get("kind") == "a"]
if items:
do_something(items)

"list" ist ein built-in, deshalb verwende ich "items" als Name.
Ich sehe allerdings nicht, warum du dicts mit einem einzigen Eintrag
verwendest; ein einziges dict statt der list erscheint mir sinnvoller:

for k, v in x.iteritems():
items = {a: b for a, b in v.iteritems() if b.get("kind") == "a"}
if items:
do_something(items)

Die dict-comprehension {...} erfordert Python 2.7, für ältere Versionen
verfüttert man eine generator expression:

items = dict((a, b) for a, b in v.iteritems() if b.get("kind") == "a")

Johannes

unread,
Apr 14, 2013, 2:39:28 PM4/14/13
to pyth...@python.org
Also, erst einmal zum Verst�ndnis:

x ist ein Dict aus Dict mit Keys 'data_i; und zugeh�rigen Dict mit Key
'item_i'. Alle 'item_i' Eintr�ge haben ein Feld 'kind'.

Du bist interessiert an den 'data'-Eintr�gen, die mindestens ein
'item_i' vom kind a haben.

also an
[item for item in inner_items.values()
if "kind" in item.keys() and item['kind' == "a"]


im konkretem Fall unten w�re es also:

for key, value in x.iteritems():
items_to_work on = [item for item in value.values()
if "kind" in item.keys() and item['kind' == "a"]
if len(items_to_work_on) > 0:
pass //do some stuff here

lg,
Johannes

Philipp Kraus

unread,
Apr 14, 2013, 2:40:37 PM4/14/13
to Peter Otten, pyth...@starship.python.net

Am 14.04.2013 um 20:29 schrieb Peter Otten:

> Philipp Kraus wrote:
>
>> Ich stehe aktuell auf dem Eintrag data1, also auf meiner äußeren
>> Schleife und nun will ich wissen, ob sich in meinen data1.values
>> ein Eintrag findet, der ein kind == a enthält, wenn ja möchte ich alle
>> diese Einträge haben und mit diesen etwas machen, in etwas so:
>>
>> for k,v in x.iterateitems() :
>>
>> list = []
>> for a,b in v.iterateitems() :
>> if b.has_key("kind") and b["kind"] == "a" :
>> list.append(dict(a,b))
>>
>> if list :
>> do_something(list)
>
> Das ist äquivalent zu
>
> for k, v in x.iteritems():
> items = [{a: b} for a, b in v.iteritems() if b.get("kind") == "a"]
> if items:
> do_something(items)
>

ah, ich kannte das "get" nicht
das passt aber


> "list" ist ein built-in, deshalb verwende ich "items" als Name.
> Ich sehe allerdings nicht, warum du dicts mit einem einzigen Eintrag
> verwendest; ein einziges dict statt der list erscheint mir sinnvoller:

es sind hier mehrere Einträge - ich hatte in dem Bsp ... in dem dict geschrieben,
da stehen definitiv noch mehr Einträge drin ähnlich zu einer JSON Struktur,
nur dass bei mir auch callable Sachen drin stehen können.


Danke

Phil

Philipp Kraus

unread,
Apr 14, 2013, 3:50:21 PM4/14/13
to Johannes, pyth...@python.org
Hi,

danke für den netten Post.


Am 14.04.2013 um 20:39 schrieb Johannes:

> Also, erst einmal zum Verständnis:
>
> x ist ein Dict aus Dict mit Keys 'data_i; und zugehörigen Dict mit Key
> 'item_i'. Alle 'item_i' Einträge haben ein Feld 'kind'.
>
> Du bist interessiert an den 'data'-Einträgen, die mindestens ein
> 'item_i' vom kind a haben.

Ja


>
> also an
> [item for item in inner_items.values()
> if "kind" in item.keys() and item['kind' == "a"]
>
>
> im konkretem Fall unten wäre es also:
>
> for key, value in x.iteritems():
> items_to_work on = [item for item in value.values()
> if "kind" in item.keys() and item['kind' == "a"]
> if len(items_to_work_on) > 0:
> pass //do some stuff here

Ich wollte halt die verschachtelten Schleifen vermeiden und es eben kompakter bekommen.


>
> On 14.04.2013 17:44, Philipp Kraus wrote:
>> Hallo,
>>
>> ich habe folgendes dict:
>> x = {
>>
>> "data1" : {
>> "item 1" : {
>> "kind" : "a"
>> ....
>> } ,
>>
>> "item 2" : {
>> "kind" : "a"
>> ....
>> },
>>
>> "item 3" : {
>> "kind" : "b"
>> ....
>> }
>> },
>> ....
>> }
>>
>>
>> ich durchlaufe das dict so:
>>
>> for key, value in x.iteritems() :
>> y = ?
>> if y :
>> do something with y
>>
>>
>> Ich möchte an der Stelle ? prüfen, ob sich innerhalb der Kindelemente
>> von value ein Feld
>> mit dem Typ "a" enthält, wenn dies der Fall ist, soll der if Zweig
>> ausgeführt werden. Ich würde
>> jetzt mit filter versuchen das zu lösen und dann via if prüfen, ob die
>> Liste leer ist. Geht das
>> vielleicht irgendwie kompakter z.B.
>>
>> if any(value.items.child("kind") == "a")
>>
>> Danke
>>
>> Phil
>>

Philipp Kraus

unread,
Apr 14, 2013, 4:15:08 PM4/14/13
to python-de@python.org Python Mailingliste Deutsche
Ich habe das aktuell so:

  for tablename, tabledata in x.iteritems() :
     items = dict((contentname, contentdata) for contentname, contentdata in tabledata.iteritems() if contentdata.get("kind") == "a")

damit habe in items die Elemente drin, die ich brauche. Ich übernehme aber damit alle Daten aus dem ursprünglichen dict (item i). Kann ich nun noch verschiedene Felder ausschließen?
Also letztendlich so etwas

items = dict((contentname, contentdata) if not contentname in ["kind", "type"] for contentname, contentdata in tabledata.iteritems() if contentdata.get("kind") == "a")
?
d.h. ich möchte aus dicts item i noch verschiedene Elemente entfernen

Danke

Phil




Am 14.04.2013 um 21:50 schrieb Philipp Kraus:

Hi,

danke für den netten Post.


Am 14.04.2013 um 20:39 schrieb Johannes:

Also, erst einmal zum Verständnis:

x ist ein Dict aus Dict mit Keys 'data_i; und zugehörigen Dict mit Key
'item_i'. Alle 'item_i' Einträge haben ein Feld 'kind'.

Du bist interessiert an den 'data'-Einträgen, die mindestens ein
'item_i' vom kind a haben.

Ja



also an
[item for item in inner_items.values()
if "kind" in item.keys() and item['kind' == "a"]


im konkretem Fall unten wäre es also:

for key, value in x.iteritems():
items_to_work on = [item for item in value.values()
if "kind" in item.keys() and item['kind' == "a"]
if len(items_to_work_on) > 0:
pass //do some stuff here

Ich wollte halt die verschachtelten Schleifen vermeiden und es eben kompakter bekommen.



On 14.04.2013 17:44, Philipp Kraus wrote:
Hallo,

ich habe folgendes dict:
x = {

"data1" : {
    "item 1" : {
               "kind" : "a"
              ....
      } ,

    "item 2" : {
               "kind" : "a"
              ....
      },

    "item 3" : {
               "kind" : "b"
              ....
      }
},
....
}


ich durchlaufe das dict so:

for key, value in x.iteritems() :
  y = ?
  if y :
       do something with y


Ich möchte an der Stelle ? prüfen, ob sich innerhalb der Kindelemente
von value ein Feld
mit dem Typ "a" enthält, wenn dies der Fall ist, soll der if Zweig
ausgeführt werden. Ich würde
jetzt mit filter versuchen das zu lösen und dann via if prüfen, ob die
Liste leer ist. Geht das
vielleicht irgendwie kompakter z.B.

if any(value.items.child("kind") == "a")

Danke

Phil

Johannes

unread,
Apr 14, 2013, 4:35:03 PM4/14/13
to pyth...@python.org
du musst dir neue Elemente erzeugen:

items = dict(
(
contentname, {
'Feld1':contentdate['Feld1'],
'Feld2':contentdate['Feld2']
}
)
for contentname, contentdata in tabledata.iteritems()
if contentdata.get("kind") == "a"
)

lg,
Johannes

On 14.04.2013 22:15, Philipp Kraus wrote:
> Ich habe das aktuell so:
>
> for tablename, tabledata in x.iteritems() :
> items = dict((contentname, contentdata) for contentname,
> contentdata in tabledata.iteritems() if contentdata.get("kind") == "a")
>
> damit habe in items die Elemente drin, die ich brauche. Ich �bernehme
> aber damit alle Daten aus dem urspr�nglichen dict (item i). Kann ich nun
> noch verschiedene Felder ausschlie�en?
> Also letztendlich so etwas
>
> items = dict((contentname, contentdata) if not contentname in ["kind",
> "type"] for contentname,
> contentdata in tabledata.iteritems() if contentdata.get("kind") == "a")
> ?
> d.h. ich m�chte aus dicts item i noch verschiedene Elemente entfernen
>
> Danke
>
> Phil
>
>
>
>
> Am 14.04.2013 um 21:50 schrieb Philipp Kraus:
>
>> Hi,
>>
>> danke f�r den netten Post.
>>
>>
>> Am 14.04.2013 um 20:39 schrieb Johannes:
>>
>>> Also, erst einmal zum Verst�ndnis:
>>>
>>> x ist ein Dict aus Dict mit Keys 'data_i; und zugeh�rigen Dict mit Key
>>> 'item_i'. Alle 'item_i' Eintr�ge haben ein Feld 'kind'.
>>>
>>> Du bist interessiert an den 'data'-Eintr�gen, die mindestens ein
>>> 'item_i' vom kind a haben.
>>
>> Ja
>>
>>
>>>
>>> also an
>>> [item for item in inner_items.values()
>>> if "kind" in item.keys() and item['kind' == "a"]
>>>
>>>
>>> im konkretem Fall unten w�re es also:
>>>
>>> for key, value in x.iteritems():
>>> items_to_work on = [item for item in value.values()
>>> if "kind" in item.keys() and item['kind' == "a"]
>>> if len(items_to_work_on) > 0:
>>> pass //do some stuff here
>>
>> Ich wollte halt die verschachtelten Schleifen vermeiden und es eben
>> kompakter bekommen.
>>
>>
>>>
>>> On 14.04.2013 17:44, Philipp Kraus wrote:
>>>> _______________________________________________
>>>> python-de maillist - pyth...@python.org
>>>> <mailto:pyth...@python.org>
>>>> http://mail.python.org/mailman/listinfo/python-de
>>>>
>>>
>>> _______________________________________________
>>> python-de maillist - pyth...@python.org <mailto:pyth...@python.org>
>>> http://mail.python.org/mailman/listinfo/python-de
>>
>> _______________________________________________
>> python-de maillist - pyth...@python.org <mailto:pyth...@python.org>

Peter Otten

unread,
Apr 14, 2013, 4:41:52 PM4/14/13
to pyth...@starship.python.net
Philipp Kraus wrote:

> Ich habe das aktuell so:
>
> for tablename, tabledata in x.iteritems() :
> items = dict((contentname, contentdata) for contentname, contentdata
> in tabledata.iteritems() if contentdata.get("kind") == "a")
>
> damit habe in items die Elemente drin, die ich brauche. Ich übernehme aber
> damit alle Daten aus dem ursprünglichen dict (item i). Kann ich nun noch
> verschiedene Felder ausschließen? Also letztendlich so etwas
>
> items = dict((contentname, contentdata) if not contentname in ["kind",
> "type"] for contentname, contentdata in tabledata.iteritems() if
> contentdata.get("kind") == "a") ? d.h. ich möchte aus dicts item i noch
> verschiedene Elemente entfernen

Das wird langsam unübersichtlich; ich rate dir dazu, diesen Schritt in eine
eigene Funktion auszulagern:

def filter_data(d, excluded=frozenset(["kind", "type"])):
return dict((k, v) for k, v in d.iteritems() if k not in excluded)

for ...
items = dict((contentname, filter_data(contentdata)) ...
...

Philipp Kraus

unread,
Apr 18, 2013, 4:45:42 PM4/18/13
to
Ja danke, ich konnte meine Datenstruktur vereinfachen, damit hat sich
das problem dann erledigt.

Phil

0 new messages