Frage zu List Comprehension (Nested Loop)

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
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,

also versuche gerade List Comprehensions zu verstehen.
Aks Übung versuche ich folgenden Code in einer Zeile aus zu drücken.

Code: Alles auswählen

roots = ["asdhjh", "sadjj"]
for root in roots:
    for path, dirs, files in os.walk(root):
        print path
Ich habe es nun so Probiert.

Code: Alles auswählen

roots = ["asdhjh", "sadjj"]
for path, dirs, files in [os.walk(root) for root in roots]:
    print path
Das ganze wirft nun aber einen Fehler.
ValueError: need more than 0 values to unpack

Ich denke das Problem ist, das ich zwar eine Liste mit Generatoren
erzeuge aber nicht der einzelne Generator genutzt wird um die Schleife mit path etc zu bestücken sondern
er sich auf die Liste selber bezieht. Versteht ihr was ich meine?
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

os.walk gibt ein Tupel zurück, dass aus 3 Elementen besteht. Daher kannst du es im ersten Beispiel auch entpacken. Im zweiten Beispiel wird allerdings eine Liste aus 2 Elementen erstellt, die du mit 3 Namen entpacken willst.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

derdon hat geschrieben:os.walk gibt ein Tupel zurück, dass aus 3 Elementen besteht.
Eben nicht. os.walk gibt ein Generator-Objekt zurück.
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

@/me
Jo, es gibt einen Generator zurück.
Nur wie mache ich das den nu?

Ich muss ihn ja irgendwie dazu bringen nicht die Liste entpacken zu wollen sondern das er sich da auf die einzelnen Generatoren bezieht.
Nur wie?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Ich würde hier nicht zwanghaft versuchen, mit einer List Comprehension zu arbeiten.

Nicht jedes Sprachfeature ist an jeder Stelle angemessen.
BlackJack

@p90: Du willst hier ja auch gar keine Liste erzeugen, das ist aber der Einsatzzweck von "list comprehensions". Wenn Du das möglichst "flach" haben möchtest, wäre das hier eine Möglichkeit:

Code: Alles auswählen

import os
from itertools import chain, imap

def main():
    roots = ['bin', 'txt']
    for path, dirs, files in chain.from_iterable(imap(os.walk, roots)):
        print path
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,

hm, ja das stimmt natürlich.
Würde halt nur gerne verstehen wie das ganze genau Funktioniert.
Besonders ärgerlich ist das ganze da ich den Code schon funktionierend gesehen habe und es selber gerade nicht hin bekomme grr.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

p90 hat geschrieben:Besonders ärgerlich ist das ganze da ich den Code schon funktionierend gesehen habe und es selber gerade nicht hin bekomme grr.
Wenn du unbedingt eine LC möchtest, dann bau doch BlackJacks Vorschlag einfach um :mrgreen: :

Code: Alles auswählen

import os
from itertools import chain, imap

def main():
    roots = ['bin', 'txt']
    for path, dirs, files in [data for data in chain.from_iterable(imap(os.walk, roots))]:
        print path
BlackJack

@p90: *Den* Code hast Du sicher noch nicht als LC gesehen, weil der sich eben nicht für eine LC eignet. Wenn Du das wirklich umformst, dann müsste der Code im inneren Schleifenkörper auch in der inneren LC landen. Da ``print`` aber eine Anweisung ist, geht das nicht. Falls ``print`` eine Funktion ist (Python 3.x) oder Du eine entsprechende Funktion dafür ersetzt, dann hättest Du aber LCs deren Wert, also die erzeugten Listen, Du überhaupt nicht benötigst, und damit ist das einfach kein vernünftiger Anwendungsfall für LCs.
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,

ne was ich damit sagen wollte war das ich bereits Einzeiler gesehen habe die das über verschachtelte Schleifen lösen.
Also das man os.walk für mehrere Verzeichnisse abruft.
Aber naja, was solls.
Das mit den getrennten Schleifen ist eh besser lesbar und mittlerweile habe ich auch ne Menge über Generatoren und LC verstanden. Hat sich also gelohnt!
Danke für die Hilfe!
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Hier stand mal eine Lösung, aber die war quatsch...:(
BlackJack

@Darii: Das gibt eine Ausnahme:

Code: Alles auswählen

UnboundLocalError: local variable 'root' referenced before assignment
Antworten