loop counter ändern

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
lunas
User
Beiträge: 87
Registriert: Samstag 2. Dezember 2006, 10:56

Hi,

gibt es in Python die Möglichkeit den Schleifenzähler zu ändern.

Das

Code: Alles auswählen

for i in range(10):  
  if i == 5:
    i -= 1
  print i
funktioniert nicht. Scheinbar ist 'i' nur eine Kopie der Zählervariable, die intern verwaltet wird. Die Ausgabe sieht so aus:

Code: Alles auswählen

0
1
2
3
4
4
6
7
8
9
Allerdings sollte der Zähler nicht über 5 hinauskommen...

Hat jemand eine Idee?
lunas
User
Beiträge: 87
Registriert: Samstag 2. Dezember 2006, 10:56

Natürlich lässt sich das Problem auch mit einer While-Schleife lösen... Aus Interesse wüsste ich aber doch gerne, ob sich der Zähler manipulieren lässt.
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

gibt es in Python die Möglichkeit den Schleifenzähler zu ändern.
Nicht in so, wie du es versuchst. Du könntest, wenn du wirklich das Zählverhalten ändern möchtest, eine While-schleife nutzen:

Code: Alles auswählen

i = 0
while i < 10:
  # hier dein code
Das wäre allerdings auch eine Endlosschleife, da i logischerweise nie über 10 herauskommt (dafür sorgst du ja selber).

Du könntest dir einen Iterator schreiben, welcher dir erlaubt, das nächste Element zu bestimmen und diesen zum Iterieren nutzen. Das wäre vermutlich etwas oversized.

Du könntest dir eine Liste generieren, die die zahlen 1-5 und x mal 5 enthält:

Code: Alles auswählen

for i in range(5) + [5] * 5:
  print i
finde ich persönlich nicht sehr hübsch lesbar.

Einfacher wäre dies hier:

Code: Alles auswählen

for i in range(10):
  print min(i, 5)
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

lunas hat geschrieben:Natürlich lässt sich das Problem auch mit einer While-Schleife lösen... Aus Interesse wüsste ich aber doch gerne, ob sich der Zähler manipulieren lässt.
Ok, wenn der Wissensdurst dich treibt, versuche ich mal eine Erklärung:

for bindet die Variablennamen auf der linken Seite (i) bei jedem Durchlauf an das nächste Element aus dem iterierbaren Ding (range(5)).
Wenn du i etwas neues zuweist, ändert das nichts an dem, was i vorher zugewiesen war, und nichts daran, welches Element das nächste von range ist.

Daher der Vorschlag mit dem Iterator aus dem ersten Post. Du könntest einen beeinflussbaren Iterator schreiben, und darüber mit for iterieren, und ggf. den Iterator (und nicht i) beeinflussen, dir als nächstes element was neues zu geben.

in etwa sowas:

Code: Alles auswählen

for i in myIterator:
  print i
  if i > 5: myIterator.decrease()
Ist aber, wie gesagt, vmtl overkill. Meistens verfolgt man, wenn man soetwas vorhat, ein Paradigma aus einer anderen Sprache, was man in Python meist nicht braucht.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich denke durch die Aufnahme von PEP 342 in Python 2.5 müsste es möglich sein, einem selbstgeschriebenen Generator zu sagen, welche Zahl als nächstes kommen soll. Ist eigentlich sogar eine witzige Idee, hat natürlich keinerlei praktischen nutzen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Es ist moeglich, und mit einigem Geschick funktionierts:

Code: Alles auswählen

def gen(iterator):
    iterator = iter(iterator)
    l = None
    while True:
        if l is not None:
            while l is not None:
                o = l
                l = (yield o) # other senders
            l = (yield o) # for the for loop
        else:
            l = (yield iterator.next())


i = 0
gr = gen(range(10))
for x in gr:
    print x
    if i%2 == 0:
        gr.send(10)
    i += 1
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Antworten