多個列表中的元素做組合的邏輯與python實現

引入

本文組合邏輯的講解,與代碼,都是基於python的。

我們在實際編程中,會遇到多個元素做組合的過程,比如,給定如下4個列表

list1 = ['A', 'B']
list2 = ['C', 'D']
list3 = ['E','F','G']
list4 = ['H', 'I']

列表中的元素(A/B/C等),這裏用的是string。實際情況中,也可以是int,或其他類型的instance(比如list)。

若要求每個list中的元素,分別於其他list的元素做組合,最終組合結果如下,該怎麼求解呢?

[['A', 'C', 'E', 'H'],
 ['A', 'C', 'E', 'I'],
 ['A', 'C', 'F', 'H'],
 ['A', 'C', 'F', 'I'],
 ['A', 'C', 'G', 'H'],
 ['A', 'C', 'G', 'I'],
 ['A', 'D', 'E', 'H'],
 ['A', 'D', 'E', 'I'],
 ['A', 'D', 'F', 'H'],
 ['A', 'D', 'F', 'I'],
 ['A', 'D', 'G', 'H'],
 ['A', 'D', 'G', 'I'],
 ['B', 'C', 'E', 'H'],
 ['B', 'C', 'E', 'I'],
 ['B', 'C', 'F', 'H'],
 ['B', 'C', 'F', 'I'],
 ['B', 'C', 'G', 'H'],
 ['B', 'C', 'G', 'I'],
 ['B', 'D', 'E', 'H'],
 ['B', 'D', 'E', 'I'],
 ['B', 'D', 'F', 'H'],
 ['B', 'D', 'F', 'I'],
 ['B', 'D', 'G', 'H'],
 ['B', 'D', 'G', 'I']]

這裏最簡單的解法,就是用4個for循環來實現。但實際情況中,list的個數是可變的,那就無法用固定個數的for訓練來實現了。

我們下面就講解這個問題的求解邏輯,與代碼實現。

組合的邏輯過程

首先,把所有list都裝在一個list中,比如

all_list = [list1, list2, list3, list4]

然後,設置一個空的result的list,用來存儲最終結果

result = [[]]

這裏是list of list,其中的內層list設置爲空list很重要,這保證了下面邏輯的正確進行。

接下來,遍歷各個子list的元素,並與result中的元素做組合:

for pool in all_list:
    tmp = []
    for x in result:
        for y in pool:
            tmp.append(x+[y])
    result = tmp   

爲了看懂上面代碼的組合邏輯過程,我們寫一個簡化的實例,如下:

all_list = [['A','B'],['C','D','E']]
result = [[]]

for pool in all_list:
    tmp = []
    for x in result:
        for y in pool:
            tmp.append(x+[y])
            print(tmp)
    result = tmp   

跑起來,得到的輸出如下

[['A'], ['B']]
[['A', 'C'], ['A', 'D'], ['A', 'E']]
[['A', 'C'], ['A', 'D'], ['A', 'E'], ['B', 'C'], ['B', 'D'], ['B', 'E']]

通過輸出,可以看到,組合的過程,就是

  1. 先把list1的元素(['A','B']),append到result中
result = [['A'], ['B']]
  1. 把上面的result與list2中每個元素(['C','D','E'])做組合,再更新result
result = [['A', 'C'], ['A', 'D'], ['A', 'E'], ['B', 'C'], ['B', 'D'], ['B', 'E']]
  1. 如果還有list3,再進行2的過程

這裏有個小經驗,就是將多個list放入一個list中,就避免了for的個數不確定的問題。

最終,使用這段代碼,就解決了本文開頭提出的問題:

all_list = [['A', 'B'], ['C', 'D'], ['E','F','G'], ['H', 'I']]
result = [[]]

for pool in all_list:
    tmp = []
    for x in result:
        for y in pool:
            tmp.append(x+[y])
    result = tmp   

print(result)

使用itertools

上面的邏輯過程,已經被itertools做了更強大的實現,可以用更簡潔的代碼來解決問題:

import itertools
all_list = [['A', 'B'], ['C', 'D'], ['E','F','G'], ['H', 'I']]
list(itertools.product(*all_list))

注意,*all_list的用法,是爲函數傳入多個參數(不確定參數個數)的語法。

itertools很多源代碼都放到文檔中了,可以在[1]中查看itertools的很多方法源碼。

上面的代碼,其實就是itertools中product的部分源碼。

參考

  • [1] https://docs.python.org/3/library/itertools.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章