# Print out numbers of increasing distance from center value in Python

I am trying to print out numbers by increasing positive and negative values around a center number, and I don't think I've found the best way. For example, say I want to find what number in a list my center value is closest to. I do that by adding one, see if it matches, then subtracting one from the original number and see if that matches, then add two from the original number and so on. I know there are other ways of finding the closest match but I'm not looking for that - I'm looking for the best way to print out numbers steadily getting farther from a center value. Here's my code:

def inc_val(center, i, neg_toggle):
mult = 1
if neg_toggle:
neg_toggle = False
mult = -1
else:
neg_toggle = True
mult = 1
i += 1
val = center + (i * mult)
return val, i, neg_toggle

i = 0
center = 24
val = center
neg_toggle = False
my_set = {30, 50, 90}
while val not in my_set:
print(val)
val, i, neg_toggle = inc_val(center, i, neg_toggle)


This prints out the following list, as desired:

24
25
23
26
22
27
21
28
20
29
19


To be clear, I'm interested in the incrementing numbers. The while not in my_set part is just to illustrate. I am not intentionally trying to re-invent anything, so if there's a built-in or simpler way to do this, please let me know.

## 1 Answer

Rather than maintaining the state of the iteration using three variables val, i, and neg_toggle, it would be more elegant to write a generator. Then, the state of the iteration would be maintained by the flow of the execution of the generator itself.

def zoom_out(center):
decr = center
incr = center + 1
while True:
yield decr
decr -= 1
yield incr
incr += 1

for n in zoom_out(24):
if n in (30, 50, 90):
break
print(n)


Furthermore, fancy iteration can often be expressed more elegantly using itertools. Here, I'd take advantage of itertools.count() to implement the generator, and itertools.takewhile() to detect when to stop executing the infinite generator.

from itertools import count, takewhile

def zoom_out(center):
decr = count(center, -1)
incr = count(center + 1)
while True:
yield next(decr)
yield next(incr)

for n in takewhile(lambda n: n not in (30, 50, 90), zoom_out(24)):
print(n)