簡體   English   中英

Itertools而不是嵌套循環

[英]Itertools instead of nested loops

list_a = [] 
for color in [True,False]:
    for piece in range(1,7):
        list_a = list_a + function(piece,color)

在這里, function(piece,color)返回一個列表,我想加入該列表並最終返回長列表,在這里可以使用itertools.chain嗎? 因為我認為它可能會更快。 我僅顯示一個示例,但是在我的實際代碼中,循環運行了大約100,000次,這就是為什么我在尋找更快的方法。

我將回答您應該問的問題;-)

這個:

list_a = list_a + function(piece,color)

花費的時間是執行次數的二次方。 每次創建一個全新的列表對象時,將復制整個舊list_a和新列表。

因此,如果它多次執行,則可以通過將其更改為以下內容來獲得巨大的改進:

list_a.extend(function(piece,color))

然后,在可能的情況下將list_a擴展為“就位”; 在幕后,它可能需要不時地復制到更大的存儲區域,但是總的來說,攤銷的時間在執行的次數上是線性的。

如果您真的想使用itertools.chain

>>> from itertools import product, chain
>>> list_a = list(chain.from_iterable(function(piece, color) for piece, color in product([True, False], range(1, 7))))

當然,如果使用list_a += function(piece, color) ,則速度可能會一樣快(也許更快?)。

list_a = list_a + function(piece, color)的問題在於該行在輸入中是二次方的,因為它建立了一個全新的列表,而list_a += function(piece, color)相當於使用extend ,對於Python列表是攤銷的固定時間,因此內部部分保持線性而不是二次線性。

yield from似乎是這里的簡單解決方案。

def generator():
    for color in [True,False]:
        for piece in range(1,7):
            yield from function(piece,color)

您可以使用itertools.starmap ,盡管仍然有循環,但您無法真正擺脫循環:

result_generator = starmap(function, ((piece, color) for piece in range(1,7) for color in [True,False]))

list_a = list(result_generator)

然后,像這樣使用itertools.product

result_generator = starmap(function, product(range(1,7), [True,False]))

暫無
暫無

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

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