使用itertools.product并想要播种值

使用itertools.product并想要播种值,第1张

使用itertools.product并想要播种值

这是一个基于pypy库代码的解决方案(感谢agf在评论中的建议)。

状态可以通过

.state
属性获得,也可以通过
.goto(state)
位置
state
序列索引(从0开始)进行重置。最后有一个演示(恐怕您需要向下滚动)。

这比丢弃值要快得多。

> cat prod.pyclass product(object):    def __init__(self, *args, **kw):        if len(kw) > 1: raise TypeError("product() takes at most 1 argument (%d given)" %       len(kw))        self.repeat = kw.get('repeat', 1)        self.gears = [x for x in args] * self.repeat        self.num_gears = len(self.gears)        self.reset()    def reset(self):        # initialization of indicies to loop over        self.indicies = [(0, len(self.gears[x]))   for x in range(0, self.num_gears)]        self.cont = True        self.state = 0    def goto(self, n):        self.reset()        self.state = n        x = self.num_gears        while n > 0 and x > 0: x -= 1 n, m = divmod(n, len(self.gears[x])) self.indicies[x] = (m, self.indicies[x][1])        if n > 0: self.reset() raise ValueError("state exceeded")    def roll_gears(self):        # Starting from the end of the gear indicies work to the front        # incrementing the gear until the limit is reached. When the limit        # is reached carry operation to the next gear        self.state += 1        should_carry = True        for n in range(0, self.num_gears): nth_gear = self.num_gears - n - 1 if should_carry:     count, lim = self.indicies[nth_gear]     count += 1     if count == lim and nth_gear == 0:         self.cont = False     if count == lim:         should_carry = True         count = 0     else:         should_carry = False     self.indicies[nth_gear] = (count, lim) else:     break    def __iter__(self):        return self    def next(self):        if not self.cont: raise StopIteration        l = []        for x in range(0, self.num_gears): index, limit = self.indicies[x] l.append(self.gears[x][index])        self.roll_gears()        return tuple(l)p = product('abc', '12')print list(p)p.reset()print list(p)p.goto(2)print list(p)p.goto(4)print list(p)> python prod.py [('a', '1'), ('a', '2'), ('b', '1'), ('b', '2'), ('c', '1'), ('c', '2')][('a', '1'), ('a', '2'), ('b', '1'), ('b', '2'), ('c', '1'), ('c', '2')][('b', '1'), ('b', '2'), ('c', '1'), ('c', '2')][('c', '1'), ('c', '2')]

您应该对其进行更多测试-我可能犯了一个愚蠢的错误-但是这个想法很简单,因此您应该可以解决它:o)您可以自由使用我的更改;不知道原始的pypy许可证是什么。

也不

state
是真正的完整状态-它不包括原始参数-只是序列的索引。也许最好把它称为索引,但是代码中已经有索引了。

更新

这是一个简单的版本,具有相同的想法,但是可以通过转换数字序列来工作。因此,您只需将

imap
count(n)
偏移量即可
n

> cat prod2.pyfrom itertools import count, imapdef make_product(*values):    def fold((n, l), v):        (n, m) = divmod(n, len(v))        return (n, l + [v[m]])    def product(n):        (n, l) = reduce(fold, values, (n, []))        if n > 0: raise StopIteration        return tuple(l)    return productprint list(imap(make_product(['a','b','c'], [1,2,3]), count()))print list(imap(make_product(['a','b','c'], [1,2,3]), count(3)))def product_from(n, *values):    return imap(make_product(*values), count(n))print list(product_from(4, ['a','b','c'], [1,2,3]))> python prod2.py [('a', 1), ('b', 1), ('c', 1), ('a', 2), ('b', 2), ('c', 2), ('a', 3), ('b', 3), ('c', 3)][('a', 2), ('b', 2), ('c', 2), ('a', 3), ('b', 3), ('c', 3)][('b', 2), ('c', 2), ('a', 3), ('b', 3), ('c', 3)]

(这里的缺点是,如果您要停止并重新启动,则需要跟踪自己已使用了多少个)



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5645113.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存