2

Is it possible to prevent the for loop from proceeding to the next value in the list/iterator if a certain condition is satisfied?

lst = list('abcde')
for alphabet in lst:
  if some_condition:
     # somehow prevent the for loop from advancing so that in the
     # next iteration, the value of alphabet remains the same as it is now
  # do something
5
  • Do I understand that you intend to cause the current loop iteration to be reexecuted (value of alphabet remains the same) until the condition isn't met? Commented Aug 19, 2011 at 16:44
  • @Michael: Yes, and that is exactly what i want. Commented Aug 19, 2011 at 16:46
  • By the way, there is no need to make a list--strings are already iterable. You can just do for letter in 'abcde': Commented Aug 19, 2011 at 16:49
  • @Mike Graham: I know that but I wanted to emphasize lst which in my case is a hodge-podge of many types! Commented Aug 19, 2011 at 16:56
  • Lists are typically used for homogeneous collections. If that isn't what you have, iterating over it can be a bit precarious. Commented Aug 19, 2011 at 18:55

4 Answers 4

8

What you seem to want is a nested while loop. Only when the while loop exits will the for loop continue to the next value.

alphabet = "abcdefghijklmnopqrstuvwxyz"
for letter in alphabet:
  while some_condition:
     # do something
Sign up to request clarification or add additional context in comments.

Comments

4

You can use break to exit the loop immediately, or continue to skip to the next iteration of the loop. See http://docs.python.org/tutorial/controlflow.html for more details.

Edit: Actually, upon closer inspection, what you're looking for is a rather odd case. Have you considered something like

lst = list('abcde')
specialcase = ""
for alphabet in lst:
  if specialcase != "":
       alphabet = specialcase
       specialcase = ""
  elif some_condition:
     # somehow prevent the for loop from advancing so that in the
     # next iteration, the value of alphabet remains the same as it is now
     specialcase = alphabet
  #do something

You'll have to modify this to suit your particular situation, but it should give you the idea.

5 Comments

I do not want it to continue. I want it to pause. The values of alphabet at each iteration should be 'a','b','c','c','d','e' for example.
I have tried that and it doesn't work. The value of alphabet in that iteration is set to specialcase and that value in lst is skipped. So, alphabet would take values 'a','b','c','c','e' (no 'd').
wouldn't you be skipping some elements?
@Manu There, try that. Again, I don't know exactly how your loop is structured, so I'm guessing here. Depending on your needs, that elif might need to be changed to an if, if you want to check that condition on every iteration regardless.
@Jared: Yep. That did it. But i'm accepting Dmitry's answer as his stack idea simplifies certain other things in the rest of my program.
2

Do the loop manually but be carefull not to be stuck

>>> i = 0
>>> j = 0
>>> abc = 'abcdefg'
>>> while i < len(abc):
...     print abc[i]
...     if abc[i] == 'd' and j == 0:
...         print 'again'
...         j = 1
...         i -= 1
...     i += 1
a
b
c
d
again
d
e
f
g

Another one using for but kind of a hack

>>> labc
4: ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> flag
5: True
>>> for i in labc:
...     print i
...     if i == 'd' and flag:
...         flag = False
...         labc[labc.index(i):labc.index(i)] = [i]
a
b
c
d
d
e
f
g

1 Comment

Nice hack. But this modifies the original list for which i have to make a copy of the original just for this loop. And that doesn't quite cut it for very large lists.
0

I don't think you can (or should) do this with a regular for list-iterator. You may want to look at this as a case of a work queue and use a while loop:

work_stack = list('abcde')

prev_item = ''
while work_stack:
    item = work_stack.pop(0)
    print item
    if prev_item=='a' and item == 'b':
        work_stack.insert(0,item)
    prev_item = item

4 Comments

This is unnecessarily quadratic.
Meaning that the time it takes to exhaust this list in the limit is proportional to the length squared, when this could be implemented merely proportional to the length of the list. This is because inserting and popping from the front of a list is expensive. Are you familiar with en.wikipedia.org/wiki/Big_O_notation ?
What you are doing is premature optimization. I'm making no assumptions about how the list is implemented or whether the size is even an issue (that's not the original question asked). If the OP wants, he can adopt the solution I offer to a true stack implementation based on a linked list where the inserts are done in a constant time.
Or you could just reverse the list... Or you could just use a deque... When the O(n**2) solution is exactly as simple as (or, like in kindall's answer, simpler than) the O(n) solution, it is not premature to adopt the O(n) solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.