key, value aus list comprehension

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
tekknokrat
User
Beiträge: 7
Registriert: Dienstag 31. August 2010, 09:44

Hallo zusammen,

wie kriege ich in folgendem Code auch k ausgegeben?

Code: Alles auswählen

pattern = { 'test' : ['ABC', '[a-z]{1,3}', '\bP\b' ], 'test2': [ 'WAS', 'ORA' ] }

for v  in ( v for k in pattern for v in pattern[k] ) :
  print v
also ungefähr so:

Code: Alles auswählen

pattern = { 'test' : ['ABC', '[a-z]{1,3}', '\bP\b' ], 'test2': [ 'WAS', 'ORA' ] }

for (k, v)  in ( v for k in pattern for v in pattern[k] ) :
  print "Key %s, Value %s" % (k, v)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Du meinst:

Code: Alles auswählen

In [1]: pattern = { 'test' : ['ABC', '[a-z]{1,3}', '\bP\b' ], 'test2': [ 'WAS', 'ORA' ] }

In [2]: for k, v in pattern.items():
   ...:     print k, v
   ...:     
test ['ABC', '[a-z]{1,3}', '\x08P\x08']
test2 ['WAS', 'ORA']
Oder etwas anderes?
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Warum eine LC? Versteh' ich jetzt den Sinn nicht... Warum nicht einfach das dict abfragen?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@cofi:
Das hatte ich mich jetzt nicht getraut, hab' da vorhin schon 'nen Rüffel bekommen... :mrgreen:
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
tekknokrat
User
Beiträge: 7
Registriert: Dienstag 31. August 2010, 09:44

@mutetella:
Ich möchte nicht die Listen als Value zurückbekommen sondern die einzelnen Einträge der Listen. Im ersten Beispiel kommt ja schon folgendes zurück:
ABC
[a-z]{1,3} P
WAS
ORA
Ich möchte aber folgendes zurückbekommen:
Key: test Value: ABC
Key: test Value: [a-z]{1,3} P
Key: test2 Value: WAS
Key: test2 Value: ORA
Die LC will ich, um mir die innere Schleife zu sparen und die Schleife beim ersten Match (es handelt sich um reguläre Ausdrücke in der Liste) verlassen zu können.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

tekknokrat hat geschrieben:... sondern die einzelnen Einträge der Listen [...] Die LC will ich, um mir die innere Schleife zu sparen...
- Wenn Du einzelne Einträge einer Liste willst, dann kommst Du daran nur über eine Schleife, selbst wenn bereits der 1. Eintrag ein Treffer sein sollte und Du damit aussteigen möchtest.
- Eine LC ist eine Schleife
- Somit sparst Du Dir keine "innere Schleife"

Solche Sachen sind nicht unüblich:

Code: Alles auswählen

iterable = [1, 2, 3, [4, 5, 6]]
for element in iterable:
    if isinstance(element, (list, tuple)):
        for inner in element:
            print inner
    else:
        print element
Oder habe ich Dich immer noch nicht verstanden?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo tekknokrat,

da Du in Deiner äußersten Schleife auf k zugreifen willst, muß es auch im Ergebnis Deiner LC erscheinen:

Code: Alles auswählen

for k,v in ( (k,v) for k,w in pattern.iteritems() for v in w):
    print "Key %s, Value %s" % (k, v)
Grüße
Sirius
tekknokrat
User
Beiträge: 7
Registriert: Dienstag 31. August 2010, 09:44

Hallo,

Genau das Konstrukt von Sirius habe ich gesucht. Danke euch!
tekknokrat
User
Beiträge: 7
Registriert: Dienstag 31. August 2010, 09:44

Nochmal ein kleines Beispiel um zu verdeutlichen wofür die obige CL noch gut sein kann.
os.path gibt als 3.Tuple auch eine Liste (aller Dateien) zurück:

Code: Alles auswählen

#!/usr/bin/python

import os
ext = None

for path in ( os.path.join(p[0],f) for i,p in enumerate(os.walk('.')) for f in p[2] if not ext or os.path.splitext(f)[1] == ".%s" % ext ):
  print path
BlackJack

@tekknokrat: Das sprengt so ein ganz klein wenig die 80-Zeichen-Grenze.

Das `i` wird nirgends benutzt. Dafür könnte man das `p` auf Namen entpacken.

Wenn man den Punkt mit in `ext` nimmt, muss man ihn nicht für jeden Vergleich erneut in eine Zeichenkette formatieren. Und das Aufteilen an der Erweiterung kann man sich im Grunde auch sparen wenn man einfach `endswith()` verwendet. Und wenn man dann für „keine Endung” die leere Zeichenkette benutzt, kann man sich das ``not ext or`` auch noch sparen.

Code: Alles auswählen

    ext = ''
    
    for path in (
        os.path.join(path, filename)
        for path, _, filenames in os.walk('.')
        for filename in filenames if filename.endswith(ext)
    ):
        print path
tekknokrat
User
Beiträge: 7
Registriert: Dienstag 31. August 2010, 09:44

Danke, sieht' schick aus! Ich dachte die String Funktionen werden ab 3.0 zusammengeschrumpft von daher hab ich das aus dem os-Modul genommen.
BlackJack

@tekknokrat: Die Funktion im `string`-Modul, die es auch als Methoden auf `str`-Objekten gibt, sind in 3.0 nicht mehr da. Von der Funktionialität selbst wurde nichts gestrichen, nur wo man sie findet ist ab 3.0 „eingeschränkt”.
Antworten