counting up and then down a range in python
python
Solution
Why not use itertools `cycle` function:
from itertools import cycle
li = range(1, n+1) + range(n, 0, -1) # e.g. [1, 2, 3, 4, 4, 3, 2, 1]
it = cycle(li)
[next(it) for _ in xrange(10)] # [1, 2, 3, 4, 4, 3, 2, 1, 1, 2]
Note: previously I had answered how to run up and down, as follows:
it = cycle(range(1, n+1) + range(n, 0, -1)) #e.g. [1, 2, 3, 4, 3, 2, 1, 2, 3, ...]
Problem
I am trying to program a standard snake draft, where team A pick, team B, team C, team C, team B, team A, ad nauseum. If pick number 13 (or pick number x) just happened how can I figure which team picks next for n number of teams. I have something like: ``` def slot(n,x): direction = 'down' if (int(x/n) & 1) else 'up' spot = (x % n) + 1 slot = spot if direction == 'up' else ((n+1) - spot) return slot ``` I have feeling there is a simpler, more pythonic what than this solution. Anyone care to take a hack at it? So I played around a little more. I am looking for the return of a single value, rather than the best way to count over a looped list. The most literal answer might be: ``` def slot(n, x): # 0.15757 sec for 100,000x number_range = range(1, n+1) + range(n,0, -1) index = x % (n*2) return number_range[index] ``` This creates a list [1,2,3,4,4,3,2,1], figures out the index (e.g. 13 % (4*2) = 5), and then returns the index value from the list (e.g. 4). The longer the list, the slower the function. We can use some logic to cut the list making in half. If we are counting up (i.e. `(int(x/n) & 1)` returns False), we get the obvious index value (x % n), else we subtract that value from n+1: ``` def slot(n, x): # 0.11982 sec for 100,000x number_range = range(1, n+1) + range(n,0, -1) index = ((n-1) - (x % n)) if (int(x/n) & 1) else (x % n) return number_range[index] ``` Still avoiding a list altogether is fastest: ``` def slot(n, x): # 0.07275 sec for 100,000x spot = (x % n) + 1 slot = ((n+1) - spot) if (int(x/n) & 1) else spot return slot ``` And if I hold the list as variable rather than spawning one: ``` number_list = [1,2,3,4,5,6,7,8,9,10,11,12,12,11,10,9,8,7,6,5,4,3,2,1] def slot(n, x): # 0.03638 sec for 100,000x return number_list[x % (n*2)] ```