簡體   English   中英

嵌套列表合並時,為什么“ functools.reduce”和“ itertools.chain.from_itertools”具有不同的計算時間

[英]why 'functools.reduce' and 'itertools.chain.from_itertools' had different computation time when nested list merged

有時您應該嵌套合並到合並列表(這類似於np.flatten() )。 當列表列表如下所示時,您應該將其展平

a = [[j for j in range(0, 10)] for i in range(0, 10000)]

您有兩種解決方案可以解決它。 itertools.chain.from_iterablefunctools.reduce

%timeit list(itertools.chain.from_iterable(a))
%timeit reduce(lambda x, y: x+y, a)

您認為哪個比另一個更快?

itertools.chain.from_iterable快1000倍或更多(當列表的長度更大時)。

如果有人知道為什么會這樣,請告訴我。

永遠感謝您的支持和幫助。

是的,因為列表串聯(即使用+ )是O(N)操作。 當您執行此操作以逐步構建大小為N的列表時,它將變為O(N 2 )。

相反,使用chain.from_iterable將使用list類型構造函數簡單地遍歷最終列表中的所有N個項目,該構造函數將具有線性性能。

這就是為什么您不應該使用sum來使列表變平的原因(請注意, reduce(lambda x, y: x+y,...)只是sum )。

請注意,扁平化嵌套列表的慣用方式是使用列表理解:

[x for sub in a for x in sub]

這是一種反模式, sum方法可以防止您使用str對象:

>>> sum(['here', 'is', 'some', 'strings'], '')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sum() can't sum strings [use ''.join(seq) instead]

請注意,您的reduce / sum方法等效於:

result = []
for sub in a:
    result = result + sub

這清楚地顯示了循環中的昂貴+ 請注意,以下朴素方法實際上具有O(N)行為,而不是O(N 2 ):

result = []
for sub in a:
    result += sub

這是因為my_list += something等同於my_list.extend(something) ,而.extend (以及.append )具有攤銷的恆定時間行為,因此總的來說,它將是O(N)。

暫無
暫無

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

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