這不能與標準Python生成器來完成,因爲一些迭代必須循環多次。你必須使用某種能夠「重複」的數據類型。我創建了一個簡單的「可重複」類和一個非遞歸產品算法。 product
應該有更多的錯誤檢查,但這至少是第一種方法。簡單reiterable類...
class PermutationsReiterable(object):
def __init__(self, value):
self.value = value
def __iter__(self):
return itertools.permutations(xrange(self.value))
而且product
iteslf ...
def product(*reiterables, **kwargs):
if not reiterables:
yield()
return
reiterables *= kwargs.get('repeat', 1)
iterables = [iter(ri) for ri in reiterables]
try:
states = [next(it) for it in iterables]
except StopIteration:
# outer product of zero-length iterable is empty
return
yield tuple(states)
current_index = max_index = len(iterables) - 1
while True:
try:
next_item = next(iterables[current_index])
except StopIteration:
if current_index > 0:
new_iter = iter(reiterables[current_index])
next_item = next(new_iter)
states[current_index] = next_item
iterables[current_index] = new_iter
current_index -= 1
else:
# last iterable has run out; terminate generator
return
else:
states[current_index] = next_item
current_index = max_index
yield tuple(states)
測試:
>>> pi2 = PermutationsReiterable(2)
>>> list(pi2); list(pi2)
[(0, 1), (1, 0)]
[(0, 1), (1, 0)]
>>> list(product(pi2, repeat=2))
[((0, 1), (0, 1)), ((0, 1), (1, 0)), ((1, 0), (0, 1)), ((1, 0), (1, 0))]
>>> giant_product = product(PermutationsReiterable(100), repeat=5)
>>> len(list(itertools.islice(giant_product, 0, 5)))
5
>>> big_product = product(PermutationsReiterable(10), repeat=2)
>>> list(itertools.islice(big_product, 0, 5))
[((0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)),
((0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (0, 1, 2, 3, 4, 5, 6, 7, 9, 8)),
((0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (0, 1, 2, 3, 4, 5, 6, 8, 7, 9)),
((0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (0, 1, 2, 3, 4, 5, 6, 8, 9, 7)),
((0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (0, 1, 2, 3, 4, 5, 6, 9, 7, 8))]
你如何提出產品呢?你必須使用'.tee()',它也可以緩存迭代器來完成他們的工作。 –
或者,您需要可重新啓動的迭代器,例如如果您可以以某種方式創建每個迭代器,則只能實現您的目標,以產生與上次完整運行期間完全相同的結果。 –
@MartijnPieters我不確定(因此問題!)。問題的核心是,給外部產品實施沒有任何中間存儲。 'itertools'中,我不確定 - 在純Python中,我認爲這可能是可能的,因爲我們可以在每次需要時重新創建一個迭代器來重新啓動迭代器。 – Hooked