把一個列表拆成N個子列表的四種方法

NewJune發表於2023-04-03

  程式設計的方法往往不止一種,比如怎麼把一個Python種的列表拆成N個子列表,我們可以很容易找到N種方法,也許這就是程式設計的魅力所在。

一、列表表示式法

這種方法最為簡潔,不過可讀性差一些

 

 

 

    這個方法中,即使原始列表的數量無法被N整除,也不會出錯,其實那是因為使用列表的切片功能訪問列表時,只要切片中首位不越界,末位無所謂,這是python的一大亮點。但是看上例來說,如果我們足夠吹毛求疵,會發現它還有點不完美。拆分後的子列表,第一個和第二個子列表的長度都為3,最後一個子列表只有一個元素了,拆分不夠均勻。

    要是有一種演算法能實現,當列表長度無法被N整除時,每個列表的長度都均勻少一點,每個子列表的總長度都相差不超過1,該有多好啊?這就要提到我們的方法二了。


二、利用貪心演算法

  永遠往最短子列表中新增元素法

  先構造一個列表,內部構造N個子空列表:[[],[],[],[]] .遍歷原始列表的每個元素,當把這個元素往結果列表的哪個子列表中追加時,永遠用min方法看哪個子列表的長度最短,誰的長度最短,說明給它append的子元素最少,我們就優先給它插入新元素,思路很巧妙,程式碼如下:

 

 

 

 

 

     但是仔細一看,這個方法還是有缺點,idx = res.index(min(res, key=len))  這句(找到長度最短的子列表的下標)方法很浪費效能,也許我們不用每次都用min方法逐個判斷子列表長度來確定待追加元素的子列表。

三、發撲克牌法

    一開始每個子列表的元素本就為空,我們永遠依次給每個子列表追加元素,一輪接著一輪,這樣大家的長度就應該接近。就像發撲克牌一樣的道理。演算法上應該是這樣寫:

 

 

    作為完美主義者來講,這樣拆分列表依然有瑕疵。原始的列表為l = [1,2,3,4,5,6,7],拆分後的output=[[1, 4, 7], [2, 5], [3, 6]],怎麼感覺兩者長得不像呢?

    有沒有一種拆分列表的演算法,可以把方法一的【保留列表元素順序】和方法三【子列表數量相差不超過1】 這兩者的優點有效結合呢?

必須有啊。

 

四、動態確定長度+列表切片

    我們只需要在發牌前,先計算出每個子列表的理論長度,再從原始列表中根據切片拿到特定長度的元素給到每個子列表,不就大功告成了圖片。有了思路,程式碼那叫一個Easy。

 

 

方法四,如果我們進一步用列表表示式來最佳化,還可以更簡潔,比如就像這樣:

 

 

 

    過分的簡潔有時候也會導致更差的可讀性。螢幕前的你,更接受用上面哪種方法來拆分列表呢?

快來關注本公眾號 獲取更多爬蟲、資料分析的知識!

相關文章