我有一个按比率旋转的函数返回值作为设置,目前我使用优先级队列之类的东西来完成这项工作,但这些是什么很好的性能和pythonista 方法来做到这一点。
这是我如何需要我的函数工作的示例
我有设置:
value | ratio
A 2
B 1
C 3
以及使用该设置的函数:
setup = {'A': 2, 'B': 1, 'C': 3} #create from setup above
def process():
...
value = ...
return value
无论我调用函数,结果:
process()
>>> A
process()
>>> A
process()
>>> B
process()
>>> C
process()
>>> C
process()
>>> C
process()
>>> A
process()
>>> A
process()
>>> B
process()
>>> C
... #and so on
你的process()
对惰性评估如此开放,我会考虑使用生成器来达到同样的效果。
#To keep the keys ordered
setup = OrderedDict([('A', 2), ('B', 1), ('C', 3)])
def process():
global setup
while True:
for key in setup.iterkeys():
for value in xrange(setup[key]):
yield key
我想不出比这更pythonista的方式了。
import itertools
SETUP = {'A': 2, 'B': 1, 'C': 3}
def _build_cycle(setup):
once = itertools.chain.from_iterable(itertools.repeat(k, setup[k]) for k in setup)
return itertools.cycle(once)
def _iterator_to_rotating_function(it):
return lambda : next(it)
process = _iterator_to_rotating_function(_build_cycle(SETUP))
由于数据源是字典,因此未定义顺序。
尽管我的评论有点尖刻,但迭代器确实是这里的方式:
from itertools import cycle, chain, repeat
def process(setup):
# to use a dictionary, just change the end to in setup.items()
return cycle(chain.from_iterable(repeat(c, n) for c, n in setup))
# A namedtuple would also be appropriate here
setup = [('A', 2), ('B', 1), ('C', 3)]
it = process(setup) # global variables are of the devil
print next(it) # repeat ad nauseam
单行代码的工作方式是:
- 带有
repeat(c, n)
的生成器表达式为您提供迭代器,生成序列['A', 'A']
、['B']
和['C', 'C', 'C']
-
chain.from_iterable()
将它们加入['A', 'A', 'B', 'C', 'C', 'C']
-
cycle()
使最后一个序列无休止地重复 - 对
next()
的连续调用将从该无限序列返回值。
您需要一个全局变量或索引来传递才能进行跟踪。这是我想出的,请注意,我在全局范围内添加了一个变量索引。
index= -1
def process():
setupList = []
for key in setup:
for val in range(setup[key]):
setupList.append(key)
setupList.sort()
global index
index += 1
return setupList[index%len(setupList)]