Listenelement in einer Schleife an eine Funktion übergeben

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
dirk_sg
User
Beiträge: 4
Registriert: Dienstag 26. Juli 2011, 17:28

Hallo zusammen,

ich bin ein absoluter Pythonneuling und komme gerade nicht mehr weiter.

Der folgende Code läuft problemlos, hat aber den Nachteil, dass der Zugriff auf die Objekte der Listen nicht variabel ist:

Code: Alles auswählen

    
        # Define the required buttons for all outputs
        output_row = 0
        output_counter = 1
        button_obj_list = list()
        x_list = []
        for output in self.rr_outputs:
            output_row += 1
            lb_r =Tkinter.Label(main, text = output.description, bg="#FFFFFF", bd=5,relief="sunken", anchor="e")
            lb_r.grid(row=output_row, column=0, sticky="we")
            # Rest nicht interessant
            bt_r_m = Tkinter.Button(main, text="Start", width=7)
            bt_r_m["command"] = lambda: rrInitLightThread(self.rrconnect,self.rr_outputs[0],button_obj_list[0][1])
            bt_r_m.grid(row=output_row, column=1)
Im Prinzip würde ich gerne etwas wie

Code: Alles auswählen

            bt_r_m["command"] = lambda: rrInitLightThread(self.rrconnect,self.rr_outputs[output_row],button_obj_list[output_row][1])
verwenden.

Kann mir jemand vielleicht auf die Sprünge helfen? :D
Anosnsten hoffe ich, dass ich mich bei meinem ersten Post hier im Forum einigermaßen verständlich ausgedrückt habe.

Danke im voraus und viele Grüße,
Dirk
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Hallo,
dirk_sg hat geschrieben:Im Prinzip würde ich gerne etwas wie ... verwenden
Und warum verwendest Du es dann nicht? Über 'output_row' hast Du ja den index. Und über diesen index greifst Du auf die Liste zu. So wie Du es 'im Prinzip' ja machen willst.
Wobei Du Dir den 'output_row'-Zähler sparen kannst. Die builtin-Funktion enumerate kann das zuverlässiger übernehmen:

Code: Alles auswählen

stuff = ['1. Element', '2. Element', '3. Element']

for index, element in enumerate(stuff):
    print element
    print stuff[index]
Oder verstehe ich Dein Problem falsch?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@dirk_sg: Du suchst wohl `functools.partial()`. Und die `enumerate()`-Funktion um das manuelle hochzählen von `output_row` einzusparen.

Muss ``self.rr_outputs[output_row]`` denn sein? Du hast das in der Schleife doch schon an den Namen `output` gebunden. Ähnliche Frage zum Indexzugriff auf `button_obj_list` — kann man da nichts mit `zip()` beziehungsweise `itertools.izip()` machen?

@mutetella: Das Problem ist, dass die Namen in der ``lambda``-Funktion erst zum Zeitpunkt des Aufrufs ausgewertet werden, und da haben sie den Wert der ihnen beim letzten Schleifendurchlauf zugewiesen wurden.
dirk_sg
User
Beiträge: 4
Registriert: Dienstag 26. Juli 2011, 17:28

@mutetella: Blackjack hat mein eigentliches Problem sehr genau beschrieben. Ich bin halt auch ganz unbedarft mit Deinem Ansatz an das Thema rangegangen ... :wink:
BlackJack hat geschrieben:@dirk_sg: Du suchst wohl `functools.partial()`. Und die `enumerate()`-Funktion um das manuelle hochzählen von `output_row` einzusparen.
Danke für den Hinweis auf functools.partial(), hier muss ich mich einlesen. Gibt es vielleicht einen Link zu einem Beispiel? :)
Enumerate war mir klar, der gepostete Code ist beim Probieren gewachsen ...
BlackJack hat geschrieben:Muss ``self.rr_outputs[output_row]`` denn sein? Du hast das in der Schleife doch schon an den Namen `output` gebunden. Ähnliche Frage zum Indexzugriff auf `button_obj_list` — kann man da nichts mit `zip()` beziehungsweise `itertools.izip()` machen?
Auch hier war das Probieren der Hintergrund, wenn es klappt, dann kann ich natürlich mit 'output' arbeiten. Dem blutigen Anfänger sagen jetzt 'zip' und itertools.izip erstmal nix und auch hier muss er erst einmal etwas lesen.


Danke für Eure schnelle Hilfe und viele Grüße,
Dirk
dirk_sg
User
Beiträge: 4
Registriert: Dienstag 26. Juli 2011, 17:28

@BlackJack

Dank Deinem Hinweis konnte ich den Code drastisch vereinfachen:

Code: Alles auswählen

bt_r_m["command"] = partial(rrInitLightThread,self.rrconnect,output,bt_r_m)
Funktioniert prima!

Danke und Gruß,
Dirk
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Kurzer Hinweis noch: Wir haben hier spezielle Python-Code-Tags - damit wird Dein Code noch hübsch mit Syntax-Highlighting versehen ;-)

[ code=py ] .. [/code ] oder [ python ] .. [ / python]
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

dirk_sg hat geschrieben:@BlackJack

Dank Deinem Hinweis konnte ich den Code drastisch vereinfachen:

Code: Alles auswählen

bt_r_m["command"] = partial(rrInitLightThread,self.rrconnect,output,bt_r_m)
So etwas so schnell zu erfassen und umzusetzen fällt hier eigentlich nicht mehr unter "absoluter Neuling". :)
dirk_sg
User
Beiträge: 4
Registriert: Dienstag 26. Juli 2011, 17:28

@Hyperion: Danke für den Hinweis! Werde ich beim nächsten Mal berücksichtigen.

@/me: Ich bin recht frisch in Python, aber wenn mir jemand einen konkreten Tip gibt, dann beherrsche ich auch RTFM ... :mrgreen:

Mir gefällt's gut hier bei Euch!

Bis zum nächsten Frischlingproblem,
Dirk
Antworten