Seite 1 von 1

Frage zu List Comprehension (Nested Loop)

Verfasst: Freitag 17. Dezember 2010, 15:08
von p90
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?

Re: Frage zu List Comprehension (Nested Loop)

Verfasst: Freitag 17. Dezember 2010, 15:26
von derdon
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.

Re: Frage zu List Comprehension (Nested Loop)

Verfasst: Freitag 17. Dezember 2010, 15:41
von /me
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.

Re: Frage zu List Comprehension (Nested Loop)

Verfasst: Freitag 17. Dezember 2010, 15:51
von p90
@/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?

Re: Frage zu List Comprehension (Nested Loop)

Verfasst: Freitag 17. Dezember 2010, 15:52
von /me
Ich würde hier nicht zwanghaft versuchen, mit einer List Comprehension zu arbeiten.

Nicht jedes Sprachfeature ist an jeder Stelle angemessen.

Re: Frage zu List Comprehension (Nested Loop)

Verfasst: Freitag 17. Dezember 2010, 16:11
von 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

Re: Frage zu List Comprehension (Nested Loop)

Verfasst: Freitag 17. Dezember 2010, 16:18
von p90
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.

Re: Frage zu List Comprehension (Nested Loop)

Verfasst: Freitag 17. Dezember 2010, 16:36
von /me
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

Re: Frage zu List Comprehension (Nested Loop)

Verfasst: Freitag 17. Dezember 2010, 17:08
von 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.

Re: Frage zu List Comprehension (Nested Loop)

Verfasst: Freitag 17. Dezember 2010, 17:39
von p90
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!

Re: Frage zu List Comprehension (Nested Loop)

Verfasst: Samstag 18. Dezember 2010, 10:42
von Darii
Hier stand mal eine Lösung, aber die war quatsch...:(

Re: Frage zu List Comprehension (Nested Loop)

Verfasst: Samstag 18. Dezember 2010, 10:45
von BlackJack
@Darii: Das gibt eine Ausnahme:

Code: Alles auswählen

UnboundLocalError: local variable 'root' referenced before assignment