在python中向上计数然后向下计算一个范围

Col*_*ole 6 python

我正在尝试编制一个标准的蛇选项,其中A队选秀,B队,C队,C队,B队,A队,恶心.

如果选秀号码13(或选秀号码x)刚刚发生,我怎样才能确定哪支球队接下来会选择n队.

我有类似的东西:

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
Run Code Online (Sandbox Code Playgroud)

我觉得有一个比这个解决方案更简单,更pythonic的东西.任何人都想关注它吗?

所以我玩了一点.我正在寻找单个值的返回,而不是计算循环列表的最佳方法.最直接的答案可能是:

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]
Run Code Online (Sandbox Code Playgroud)

这会创建一个列表[1,2,3,4,4,3,2,1],计算出索引(例如13%(4*2)= 5),然后从列表中返回索引值(例如4).列表越长,功能越慢.

我们可以使用一些逻辑将列表减半.如果我们正在计数(即(int(x/n) & 1)返回False),我们得到明显的索引值(x%n),否则我们从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]
Run Code Online (Sandbox Code Playgroud)

完全避免列表是最快的:

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
Run Code Online (Sandbox Code Playgroud)

如果我将列表保存为变量而不是产生一个:

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)]
Run Code Online (Sandbox Code Playgroud)

And*_*den 7

为什么不使用itertools cycle函数:

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]
Run Code Online (Sandbox Code Playgroud)

注意:之前我已经回答了如何上下运行,如下:

it = cycle(range(1, n+1) + range(n, 0, -1)) #e.g. [1, 2, 3, 4, 3, 2, 1, 2, 3, ...]
Run Code Online (Sandbox Code Playgroud)


kre*_*tea 5

这是一台能满足您的需求的发电机.

def draft(n):
    while True:
        for i in xrange(1,n+1):
            yield i
        for i in xrange(n,0,-1):
            yield i

>>> d = draft(3)
>>> [d.next() for _ in xrange(12)]
[1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)