簡體   English   中英

如何懶惰地生成和處理來自生成器的結果組合?

[英]How can I lazily generate and process combinations of results from a generator?

我有一個生成器,我想在它上面執行一個嵌套循環,這樣內部循環將從當前外部循環所在的位置開始。 例如,我有一個生成列表[1,2,3]的生成器,我的循環應該生成: (1,2),(1,3),(2,3) 我想出的代碼如下:

from itertools import tee

def my_gen():
    my_list = [1, 2, 3]
    for x in my_list:
        yield  x

first_it = my_gen()
while True:
    try:
        a = next(first_it)
        first_it, second_it = tee(first_it)
        for b in second_it:
            print(a,b)
    except StopIteration:
        break

這段代碼很麻煩,效率不高,對我來說看起來不是很pythonic。 請注意,我不能使用combinations_with_replacement ,因為我需要一個內部循環來處理來自外部循環的特定值。

對更優雅和 Pythonic 代碼有什么建議嗎?

只重復克隆和耗盡生成的迭代器之一不是很有效。 根據itertools.tee文檔

一般來說,如果一個迭代器在另一個迭代器啟動之前使用了大部分或全部數據,那么使用 list() 而不是 tee() 會更快。

from itertools import islice

my_list = [1, 2, 3]
# or, more generally
# my_list = list(my_gen())

for i, a in enumerate(my_list):
    for b in islice(my_list, i+1, None):
        print((a, b))
(1, 2)
(1, 3)
(2, 3)

結果(1,2),(1,3),(2,3)不是笛卡爾積。 您的意思是無需重復即可獲得所有組合?

對於沒有重復的組合

使用itertools.combinations函數:

from itertools import combinations

print(list(combinations([1,2,3], 2)))

對於實際的笛卡爾積

使用列表推導,您可以將代碼簡化為更 Pythonic 和優雅的方式:

my_list = [1, 2, 3]

c_prod = [(i, j) for i in iter(my_list) for j in iter(my_list)]

print(c_prod)

另一種選擇是使用itertools.product函數:

import itertools

for i in itertools.product(my_list, my_list):
    print(i)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM