-1

Forgive me, I am new to python.

In other languages, When I want to iterate at the end of a loop, rather than at the beginning I'd use a do while loop.

Python doesn't have a do while so I have done this:

iter_ = zip(x_list, y_list)
x,y = initial_values()
while x:
    foo(x,y)
    x,y = next(iter_,(False,False))

This works fine, but I am not fully satisfied with:

  • the default (False,False) tuple. However I find it preferable to try except: StopIteration; break
  • the use of x as the condition, as x could be an element which would legitimately be interpreted as False in a logical test. However I find it preferable to introducing a separate condition variable and test in addition to the next() call

What is the best/most python idiomatic way to perform iteration at the end rather than the beginning of the loop?

OldSchool
  • 459
  • 1
  • 3
  • 14
  • 2
    Does this answer your question? [Emulate a do-while loop in Python?](https://stackoverflow.com/questions/743164/emulate-a-do-while-loop-in-python) – Olvin Roght Apr 17 '20 at 11:38
  • @OlvinRoght. I looked at that thank you. The answer I thought was best there was condition = True; while condition:condition = test_loop_condition() which is similar to my while x: x = next(iter,False). However my question has the additional aspect of wishing to iterate at the end rather than at the beginning of the loop. I have simplified the question to make that clearer – OldSchool Apr 17 '20 at 15:49

2 Answers2

0

What about:

z = set_z_for_first_pass()  
for x,y in zip(x_list,y_list):
   if not x: break
   foo(x,y,z)
   z = set_z_for_subsequent_passes()
Błotosmętek
  • 12,717
  • 19
  • 29
  • Is the `if not x:break` needed / doing anything? I don't thing the test will ever be True other than in the edge case that an element in x_list evaluates to False, and in that case, testing for False to terminate the iteration is not what you'd want. – OldSchool Apr 18 '20 at 09:48
  • Well, your original code suggested that (`while x:`); you can safely drop it. – Błotosmętek Apr 18 '20 at 09:58
  • Yes, but in my code the `while x` is testing if the iteration is finished. Hence it is needed there. In the loop you suggest that test is being performed in the `for` statement. So yes, we agree that the `if not x: break` above should be dropped. – OldSchool Apr 18 '20 at 11:37
0

I think there are two different ways of answering your question.

First, concerning the problem-solving only, I would say that your use case for using a do...while loop is artificial, and maybe comes from some other language that uses this kind of convoluted thinking. In Python, I would use:

z = calc_z_for_first_pass()
for x,y in zip(x_list, y_list) 
    foo(x,y,z)
    z = calc_z_for_subsequent_passes()

Second, there are indeed cases in which you would like to have a do...while loop, for example something like:

do:
    z = calc_z()
while not is_valid(z)

In that case, you need to manually emulate your own do...while loop (see [Emulate a do-while loop in Python? as suggested by Olvin):

while True:
    z = calc_z()
    if is_valid(z):
        break
Tawy
  • 579
  • 3
  • 14
  • I was hoping to avoid both `break` and `try: except` but I am starting to lean towards `iter_ = zip(x_list, y_list; while True: do_stuff(); try: x,y = next(iter_); except StopIteration:break`. Adding the try: else: block would also allow iteration to take place at the exact desired point in the loop. Perhaps that's the best way – OldSchool Apr 18 '20 at 09:52