Re: [問題] 如何去除迴圈後多餘的東西

作者: danny0838 (道可道非常道)   2019-12-08 19:04:45
: 推 TuCH: print(",".join([i.get('name') for i in a])) 12/05 14:06
這裡有個可以再優化的地方是把 [] 去掉,變成:
print(",".join(i.get('name') for i in a))
與原做法的差異在於原作法是 list comprehension,
會先建立一個暫時的 list,再對該 list 跑 join,然後清掉該 list,
如果 list 很大,這個暫時的 list 會佔用不少記憶體空間。
(i.get('name') for i in a) 的寫法稱作 generator expression,
(傳入函數時可省略一層括號)
它產生的是 generator,generator 是在被迭代時才即時執行,即時傳回值。
由於不須建立暫時的 list,效能較好,記憶體消耗也較少。
ref: https://www.python.org/dev/peps/pep-0289/
此外,如果要去掉 list 的最後 n 筆項目,用簡單的 list slicing 可以做到:
print(",".join(i.get('name') for i in a[:-n]))
不過這做法一樣會先建立一個暫時的新 list a[:-n],
如果想再進一步優化,可以寫成這樣:
(range 也是傳回 generator)
print(",".join(a[i].get('name') for i in range(len(a) - n)))
最後,還有一個吹毛求疵的優化是寫成:
print(*(a[i].get('name') for i in range(len(a) - n)), sep=',')
也就是把 (a[i].get('name') for i in range(len(a) - n)) 這個 generator 迭代
出來的值變成 print 的多個參數,讓它逐一印出各片段和分隔字元,
和前者的差異在於前者要先建立一個連接好的大字串,
後者不用,因此可節省記憶體及提高效能。
但是要注意,在 Python < 3.7 函數有參數上限 255 的限制,
如果 a 很長可能會導致出錯。
若有這部分疑慮,還是使用 join 比較保險。
ref: https://stackoverflow.com/questions/714475/what-is-a-maximum-number-of-arguments-in-a-python-function
總之,generator 是 Python 非常強大的功能之一,
擅用它可以讓程式碼既精簡又高效。
作者: yummy8765 (tsuyoku)   2019-12-08 23:18:00
作者: cuteSquirrel (松鼠)   2019-12-09 00:24:00
作者: TuCH (謬客)   2019-12-09 09:02:00
受益良多
作者: hongyan (Yan)   2019-12-09 12:19:00
學到了。謝謝分享
作者: froce (froce)   2019-12-10 07:43:00
推,生成器真的很好用。
作者: wargods8402 (維尼X維尼)   2019-12-10 14:03:00
推...
作者: kangapoo (kangapoo)   2019-12-11 14:55:00
優文給推
作者: plankton   2019-12-18 15:14:00
推 

Links booklink

Contact Us: admin [ a t ] ucptt.com