[英]Python list function or list comprehension
任何人都可以向我解釋這兩種創建列表的方式之間的區別。 它們是一樣的嗎? 如果不是,我應該使用哪一個?
squares1 = [x**2 for x in range(1, 11)]
squares2 = list(x**2 for x in range(1, 11))
它們的性能略有不同,如下所示:
squares1 = [x**2 for x in range(1, 11)]
每回路3.07μs±70 ns(平均值±標准偏差,7次運行,每次100000次循環)
squares2 = list(x**2 for x in range(1, 11))
每回路3.65μs±35.6 ns(平均值±標准偏差,7次運行,每次100000次循環)
這主要是因為在案例1中,您正在迭代並同時為列表生成值。
在情況2中,您在迭代時生成值,然后在它結束時將其轉換為列表,然后將其存儲為給定變量。
我這樣看,第一個程序直接通過列表理解將squares1初始化為列表。
另一個首先創建一個生成器類對象,然后將其轉換為列表。 我認為第一種方法更有效。
列表和生成器之間幾乎沒有什么區別,但根據我的知識和經驗列表,可以更快地完成工作,並且生成器可以懶散地為每次迭代產生單個結果。 對於大多數任務,我建議選擇列表。
第一種方法更快。 這是因為當它們被編譯成字節碼時,第一個變為
0 LOAD_CONST 0 (<code object <listcomp> at 0x7fc95aea9ed0, file "<dis>", line 1>)
2 LOAD_CONST 1 ('<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_NAME 0 (range)
8 LOAD_CONST 2 (1)
10 LOAD_CONST 3 (11)
12 CALL_FUNCTION 2
14 GET_ITER
16 CALL_FUNCTION 1
18 RETURN_VALUE
而第二個變成了
0 LOAD_NAME 0 (list)
2 LOAD_CONST 0 (<code object <genexpr> at 0x7fc95aea9ed0, file "<dis>", line 1>)
4 LOAD_CONST 1 ('<genexpr>')
6 MAKE_FUNCTION 0
8 LOAD_NAME 1 (range)
10 LOAD_CONST 2 (1)
12 LOAD_CONST 3 (11)
14 CALL_FUNCTION 2
16 GET_ITER
18 CALL_FUNCTION 1
20 CALL_FUNCTION 1
22 RETURN_VALUE
這意味着第二種方法需要另外兩條指令,即使它只是一點點,也會減慢速度。
在我的筆記本電腦上,第一次的百萬次迭代需要4.651秒,而第二種方法的一百萬次迭代需要5.483秒。
在第一種情況下,您使用列表理解語法。 這是在python中列出一些函數的最快方法。
在第二種情況下,您創建一個生成器
(x**2 for x in range(1000))
並立即將其發送到list()函數。 您的情況幾乎沒有區別,因為您獲得相同的列表和幾乎相同的執行時間:
%%timeit
[i**2 for i in range(1000)]
Out:
170 µs ± 774 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
list(i**2 for i in range(1000))
Out:
187 µs ± 2.45 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
但我不確定兩種情況下的內存使用情況 - 看起來都是一樣的。
兩者都是相同的。要了解更多關於列表的信息,請觀看此視頻,此視頻可能會對您有所幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.