In Liste/Tupel im Kreis laufen

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
leoel
User
Beiträge: 36
Registriert: Dienstag 25. Mai 2004, 08:54
Wohnort: Graz

Hallo!

Wie würdet Ihr das möglichst elegant lösen:

Ihr habt eine Liste/Tuple von sagen wir 20 Einträgen. Jetzt brauche ich eine Art "RoundRobin", d.h ich will durch die 20 Einträge iterieren und nach dem 20. Eintrag wieder am Anfang starten, d.h. der 21. Zugriff liefert mir den 1.Eintrag

Ad hoc fällt mir folgende Möglichkeit ein: Mit "enumerate" und einer Modulo Funktion auf den Index zugreifen.

Gibt es noch was schöneres?

Danke, Leo
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich könnt mir vorstellen, von list bzw. dict zu erben, um dort dann __getitem__ zu überschreiben, dass beim Zugriff auf object[21] der erste Eintrag kommt. Könnte auch völliger Schwachsinn sein... aber es klingt für mich zumindest ganz ok.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Hilft `itertools.cycle()` weiter?
raist1314
User
Beiträge: 52
Registriert: Dienstag 21. September 2004, 06:58
Wohnort: Adelzhausen
Kontaktdaten:

BlackJack hat geschrieben:Hilft `itertools.cycle()` weiter?
Zitat aus der Python Dokumentation:
Note, this member of the toolkit may require significant auxiliary storage (depending on the length of the iterable).
Ich würde dir eher zu einer kreisförmigen Liste raten oder du realisierst das Ganze ähnlich einer Queue. Also folgender Ablauf:
- Über die Liste laufen
- aktuelles Element von der Liste entfernen
- aktuelles Element hinten an die liste wieder anhängen

Dafür würde wohl eine eigene Klasse Sinn machen... Ich habs jetzt nicht ausprobiert, wie praktikabel das ganze ist... Vielleicht hilfts dir ja irgendwie... Ich schau mal, ob ich ein Beispiel hinkriege.

Sebastian
raist1314
User
Beiträge: 52
Registriert: Dienstag 21. September 2004, 06:58
Wohnort: Adelzhausen
Kontaktdaten:

Wenn ich mich nicht verdacht habe, kann man es mittels Queue lösen:

Code: Alles auswählen

import Queue
import time

q = Queue.Queue()
for in in xrange(0,10):
    q.put(i)

stop = False # variable zum anhalten
while not q.empty():
    if stop: break
    value = q.get() # aktuellen wert aus der queue holen
    print value
    q.put(value) # wird wieder in die queue packen
    # mach was mit value hier
    time.sleep(1)
Du musst natürlich noch Code einbauen, um die Variable stop zu setzen, damit du irgenwie die Schleife auch wieder Beenden kannst, sonst kannst du das Programm nur noch über <STRG>-C abbrechen.

Hoffe, ich konnte dir helfen...

Sebastian
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Einfach List erweitern :)

Code: Alles auswählen

class Rotater(list):
    def __getitem__(self, value):
        return super(Rotater,self).__getitem__(value % len(self))

l = Rotater()
for x in range(10):
    l.append(x)

for x in range(60):
    print l[x]
Gruss
leoel
User
Beiträge: 36
Registriert: Dienstag 25. Mai 2004, 08:54
Wohnort: Graz

Das sind echt tolle Vorschläge!

Vielen Dank, hat mir sehr geholfen...

Zusammenfassung:
- Liste überladen und mit Modulo arbeiten
- Liste mit POP und Append
- Mit der Queue arbeiten (ist logisch ähnlich zu Pop/Append)

super sache
lg Leo
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wie was das mit TMTOWTDI in Python? Sollte doch nicht sein ;)

Dumm nur, dass es schwer ist zu sagen, welcher Weg jetzt der "richtige" ist *g*.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
leoel
User
Beiträge: 36
Registriert: Dienstag 25. Mai 2004, 08:54
Wohnort: Graz

ja, das hab ich mir auch gedacht....

Im Prinzip sind es aber zwei Ansätze:
a) "Kreise" mit dem Index
b) Verschiebe die Elemente von "vorne" nach "hinten"

Was jetzt "besser" ist, muss jeder für sich entscheiden, ich hab das für mich nach *Verständlichkeit* und *Einfachheit* beurteilt.

Weiters galt für mich das Gefühl, wie sich der Code "leichter" tut (ich weiss, klingt dämlich, ist aber so) und für mich war daher der Weg den Index zu verbiegen klarer also die Elemente zu verschieben.
(vermutlich wird im C-Code von Python ohnehin nur der Pointer verschoben).

Die Performance spielt bei 20-30 Einträgen vermutlich keine Rolle...

lg Leo
BlackJack

Ich würde sagen das indexieren modulo Länge der Liste ist der "richtige" Weg. Wegnehmen und anfügen bei einer Liste kann sehr "teuer" werden weil nicht nur ein Pointer bewegt werden muss, sondern alle Elemente (Pointer) der Liste.

Der Warnhinweis bei `itertools.cycle` gilt natürlich nicht wenn die Listen/Tupel klein sind. Es wird nochmal ungefähr der Speicherplatz für die Pointer in der Liste belegt. Und zwar beim ersten Durchgang. Bei jedem weiteren Zyklus wird intern wahrscheinlich auch modulo auf die angelegte Kopie zugegriffen.

Zum TMTOWTDI: Die Gegenhaltung bei einigen Pythonistas ist übertrieben. Im Zen steht nur `There should be one -- and preferebly only one -- obvious way to do it.`, also das es nur einen offensichtlichen Weg geben sollte, nicht muss. Ausserdem kann es sein, dass man Holländer sein muss, um den zu sehen. :wink:
leoel
User
Beiträge: 36
Registriert: Dienstag 25. Mai 2004, 08:54
Wohnort: Graz

kenn ich nicht, ich bin aus Österreich, aber bei uns gibt es folgenden Spruch:
Warum einfach, wenn es kompliziert auch geht?
lg Leo
Antworten