Python loop that can count up and back down until broken

Question:

I want a loop that will count down over an iterator, then when reaching ‘the end’ it starts counting back down. I want it to do that over and over again until explicitly broken. Each time around, the loop will get shorter. Sort of like running ‘lines’ in gym class.

Here is what I have so far:

size = 8
cursize = size
rc = 0
op='add'
while cursize != 0:
    if op == 'add':
        rc += 1
    if op == 'sub':
        rc -= 1
    if rc == size-cursize:
        op = 'add'
    if rc == cursize:
        cursize -=2
        op = 'sub'
print('cursize is '+str(cursize))
print('op is '+op)
print('rc is '+str(rc))


I think the hard part here, is figuring out how to properly stop in the middle, without passing each other. I want it to get shorter from each side by a factor of 2. So if the range is say 0,20, when it hits 20, it would be 2,18 and then when it goes back to 2, it would be 4,18 then back to 18, it would become 4,16 and so forth. Where in this case 20 would be the input.

Asked By: Digitalirony

||

Answers:

Turn the iterator into a list. Each time you reach the end of an iteration, slice the list to remove the first and last elements, and also reverse it.

def loop_back_and_forth(iterator):
    list_to_loop = list(iterator)
    while list_to_loop:
        for i in list_to_loop:
            print(i)
        list_to_loop = list_to_loop[-2:0:-1]
Answered By: Barmar

You could yield from range(start, end) then adapt start and end and yield from a descending range, and repeat…

def back_and_forth(start, end):
    direc = 1
    yield start
    start += 1
    while start*direc < end*direc:
        yield from range(start, end, direc)
        start, end, direc = end - 2*direc, start, -direc

# Example use of this iterator:
print(*back_and_forth(0, 21))

This will output these numbers (I format over multiple lines):

 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 
      19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3 
       2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 
            17 16 15 14 13 12 11 10  9  8  7  6  5 
             4  5  6  7  8  9 10 11 12 13 14 15 16 
                  15 14 13 12 11 10  9  8  7 
                   6  7  8  9 10 11 12 13 14 
                        13 12 11 10  9
                         8  9 10 11 12
                              11 10
Answered By: trincot
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.