Seite 1 von 1

for-schleife in einer for-schleife

Verfasst: Montag 14. April 2008, 10:58
von meneliel
Ich habe ein kleines Syntax-Problem und komme nicht ganz weiter:
Ich habe eine for-Schleife:

Code: Alles auswählen

for element in ifilter(lambda n: n.type not in list_1 and *,iter(list_0.next,None)):
    pass
an die Stelle * müsste hin:

Code: Alles auswählen

for x in ifilter(lambda i: i not in n.name, list_2)
ich komme hier leider nicht so richtig weiter  Wie setze ich eine for-Schleife in eine For-Schleife?
Ich nehme an eine List-Comprehension könnte mir weiter helfen, aber ich komm gerade nicht drauf wie.

Oder gebe ich besser auf, das in eine Schleife zupacken? Und setze einfach eine zweite nach die erste? Also das würde ich jetzt machen, aber das ist so unschick :(

Re: for-schleife in einer for-schleife

Verfasst: Montag 14. April 2008, 11:18
von helduel
Moin,
meneliel hat geschrieben:Oder gebe ich besser auf, das in eine Schleife zupacken? Und setze einfach eine zweite nach die erste? Also das würde ich jetzt machen, aber das ist so unschick :(
Es ist eher unschick, wenn alles mit aller Gewalt in eine Zeile gepackt werden soll. Kannst ja z.B. eine Funktion definieren, die die entsprechenden Prüfungen vornimmt und diese in ifilter als erstes Argument engeben. Dann wird's gleich übersichtlicher und weniger fehleranfällig.

Gruß,
Manuel

Verfasst: Montag 14. April 2008, 11:19
von meneliel
EDIT: ich glaube, das funktioniert so sowieso nicht:
ich will nur die elemente aus Llist 0 haben, deren type nicht in list_1 vorkommt und der Name nicht in list_2

da es aber mehrere Felder (z.B) gibt, die das die "ID" im Namen enthalten und diese alle nicht erwünscht sind und ich die nicht alle extra in der List_2 führen will (dann wäre das ganze ja einfach), versuche ich das so irgendwie hinzubekommen....

Verfasst: Montag 14. April 2008, 17:19
von Leonidas
meneliel hat geschrieben:da es aber mehrere Felder (z.B) gibt, die das die "ID" im Namen enthalten und diese alle nicht erwünscht sind und ich die nicht alle extra in der List_2 führen will (dann wäre das ganze ja einfach), versuche ich das so irgendwie hinzubekommen....
Du machst das irgendwie seltsam. Statt ``ifilter`` eher eine LC nehmen oder wenn es wirklich lazy sein soll, dann eine Generator Expression.

Etwa so:

Code: Alles auswählen

typen = set([str, int, unicode])
ids = set([1, 2, 4])
gefilterte = [element for element in dein_liste if type(element) in typen and element.id in ids]

Verfasst: Dienstag 15. April 2008, 07:48
von jens
Also das wäre mir schon als LC zu lange denke ich. Ich würde ein normale Schleife machen...
Dumm eigentlich das eine LC immer auf einer line gehört... Wäre doch schön, wenn man das sauber auf mehrere Zeilen aufbauen könnte, wie eine normale Schleife, man aber keine Temporäre Variable braucht...

Also normalerweise würde ich das so machen:

Code: Alles auswählen

typen = set([str, int, unicode])
ids = set([1, 2, 4])

gefilterte = []
for element in dein_liste:
    if type(element) in typen and element.id in ids:
        gefilterte.append(element)

Verfasst: Dienstag 15. April 2008, 08:22
von meneliel
das mit der LC funktioniert, wenn ich es entsprechend anpasse. "deine_liste" ist in dem Sinne keine Liste, auf die ich so einfahc zugreifen kann, in dem Fall funktioniert das mit dem Vorschlag von jens besser.

Was ich nicht verstehe, warum muss ich aus den Listen sets machen? Ich habe ja auch keine doppelten Elemente und kann doch dann normal über die Listen iterieren?

Im Moment ist das so gelöst, ich finde es halt nur sehr unschick:

Code: Alles auswählen

for element in ifilter(lambda n: n.type not in typen and 
                     n.name not in name_list,
                     iter(meine_liste.next,None)):
    pass
Das einzige was ungünstig ist, in name_list stehen Sachen drin wie: "XY_1" "ErsteXY", "XY_irgendwas", "blaXYbla".
Nun ist es mir einfach zu umständlich, ALLE Felder mit XY extra aufzuführen, daher dachte ich an etwas wie

Code: Alles auswählen

for element in ifilter(lambda e: e not in n.name, namen_liste):
    pass
Wobei das n.name oben aus der for-Schleife kommt. Und das bekomm ich nicht so richtig zusammen gebastelt.

Verfasst: Dienstag 15. April 2008, 08:26
von jens
Also ich würde nicht auf biegen und brechen alles verkürzen. Python ist kein Perl ;)
Scheib lieber mehr zeilen Code, denn man aber viel einfacher versteht.

Verfasst: Dienstag 15. April 2008, 08:36
von meneliel
...okay.... dannn bleibt es lang ;-)
ich kann kein Perl, auch noch nie da Code gesehen :/

Verfasst: Dienstag 15. April 2008, 09:49
von BlackJack
@meneliel: Du musst aus den Listen keine `set`\s machen, aber wie Du schon selber sagtest wird bei dem ``in``-Test über die Listen iteriert. Bei `set`\s muss dieser Test nicht über die Elemente iterieren sondern kann nach Berechnung des Hash-Wertes "direkt" testen ohne alle Möglichkeiten aus zu probieren.

Verfasst: Dienstag 15. April 2008, 11:07
von meneliel
Ich glaube das Problem ist ein ganz anderes. :(

Ich will ja nur wissen ob in n.name eine Buchstabengruppe, oder halt auch ein ganzer Name aus der name_liste vorkommt.

also eher ein

Code: Alles auswählen

if element(aus name_liste) not in n.name:
    mach irgend was mit n.name
Damit ich nicht jede mögliceh Ausprägung von n.name vorher in der Liste notieren muss, die nicht erwünscht ist....

Verfasst: Dienstag 15. April 2008, 11:22
von helduel
meneliel hat geschrieben:also eher ein

Code: Alles auswählen

if element(aus name_liste) not in n.name:
    mach irgend was mit n.name
Damit ich nicht jede mögliceh Ausprägung von n.name vorher in der Liste notieren muss, die nicht erwünscht ist....
Dann suchst du wohl sowas?

Code: Alles auswählen

for name in name_liste:
    if name in n.name:
        # mach was
        break
else:
    # mach was, wenn n.name nicht in name_liste

Verfasst: Dienstag 15. April 2008, 11:42
von TheGrudge
jens hat geschrieben:... Dumm eigentlich das eine LC immer auf einer line gehört... Wäre doch schön, wenn man das sauber auf mehrere Zeilen aufbauen könnte, wie eine normale Schleife, man aber keine Temporäre Variable braucht...
Na du kannst sie doch auch aufteilen:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-


import os


files = [os.path.join(root,f)
            for root,dirs,files in os.walk("/home")
                for f in files
]
funktioniert einwandfrei...

Verfasst: Dienstag 15. April 2008, 11:49
von jens
Ja, ok das wäre eine Möglichkeit. Schön sieht das aber irgendwie nicht aus...

Verfasst: Dienstag 15. April 2008, 11:50
von TheGrudge
Nicht groß hässlicher als eine normale verschachtelte For-Schleife, wie ich finde... :D

Verfasst: Mittwoch 16. April 2008, 07:32
von meneliel
helduel hat geschrieben: Dann suchst du wohl sowas?

Code: Alles auswählen

for name in name_liste:
    if name in n.name:
        # mach was
        break
else:
    # mach was, wenn n.name nicht in name_liste
... nein eben nich. Weil genau DAS hab ich ja.... das will ich ja vermeiden, daher der Thread ;-)...bzw. suche da eine schickere Alternative. Sonst hab ich eine For-schleife und danach gleich noch eine.... das Ergebnis der zweiten ist ja eh entweder ja oder nein .... so im groben. Daher wollte ich da nicht gleich eine zweite hinter die erste packen... nur dafür dass dann raus kommt, "ja das element kommt in n.name vor" oder "nein, tut es nicht". Dachte vielleicht gibt es da einen ganz schicken Trick oder so was.

Verfasst: Mittwoch 16. April 2008, 07:35
von jens
meneliel hat geschrieben:Sonst hab ich eine For-schleife und danach gleich noch eine.... das Ergebnis der zweiten ist ja eh entweder ja oder nein ....
Was ist so schlimm daran?

Du könntest vielleicht die zweite for-Schleife in einer Funktion auslagern und die liefert dann True/False zurück...

Verfasst: Mittwoch 16. April 2008, 07:39
von meneliel
... das könnte ich tun ..... kommt mir dann aber eher vor wie mit Kanonen auf SPatzen schießen.

Schlimm daran ist nix ... dachte halt nur, es geht vielleicht schöner, kürzer, kompakter, schneller .... Hätte ja sein können ... ;-)

Danke Euch trotzdem allen. :) ... jetzt hab ich mir zumindest die Sache mit den sets noch mal angeguckt :)

Verfasst: Mittwoch 16. April 2008, 12:56
von mkesper
meneliel hat geschrieben:dachte halt nur, es geht vielleicht schöner, kürzer, kompakter, schneller ....
Programmieren: So einfach wie möglich, aber nicht einfacher! (In Anlehnung an Einstein) :D