2013-03-09 68 views
4

我想創建一個包含兩個列表的函數,這些列表不能保證長度相等,並返回兩個列表之間的所有交織。如何計算兩個列表的所有交錯?

輸入:兩個列表的大小不必相同。

輸出:保持原始列表順序的兩個列表之間的所有可能的交織。

實施例: AllInter([1,2],[3,4]) - > [[1,2,3,4],[1,3,2,4],[1,3, 4,2],[3,1,2,4],[3,1,4,2],[3,4,1,2]]

我不想要解決方案。我想要一個提示。

+4

提示:import itertools – argentage 2013-03-09 01:47:40

+0

這是一個了不起的提示 – slezica 2013-03-09 01:49:21

+0

python中的大部分列表問題都是通過記住它存在而解決的 – argentage 2013-03-09 01:51:30

回答

1

正如@airza建議的那樣,itertools模塊是您的朋友。

如果你想避免使用封裝的神奇善良,我的提示是使用遞歸。

開始打在你的心中生成列表的過程,當你發現你又在做同樣的事情,試圖找到模式。例如:

  1. 採取的第一個元素從第一個列表
  2. 任取2次,或從其他列表
  3. 無論是第一,如果你沒有從第三個或2次,或另一個從另一個列表
  4. ...

好了,開始看起來像有我們不使用一些更大的邏輯。我只是遞增數字。我一定能找到,而改變的,而不是命名更高的元素「第一個元素,一個可行的基本情況

與它玩:)

2

?提示:假設每個列表有相同的元素(但之間的不同列表),即一個列表完全是紅色的(例如它們中的r),另一個列表是藍色的(表示它們中的r),另一個列表是藍色的(表示它們中的r)

輸出的每個元素包含r + b或它們,r是紅色。

雖然你沒有要求解決方案(但他們有一個非常好的解釋)似乎像其他人已經爲你寵壞了它

所以這裏它是我寫得很快的代碼。

import itertools 

def interleave(lst1, lst2): 
    r,b = len(lst1), len(lst2) 
    for s in itertools.combinations(xrange(0,r+b), r): 
     lst = [0]*(r+b) 
     tuple_idx,idx1,idx2 = 0,0,0 
     for i in xrange(0, r+b): 
      if tuple_idx < r and i == s[tuple_idx]: 
       lst[i] = lst1[idx1] 
       idx1 += 1 
       tuple_idx += 1 
      else: 
       lst[i] = lst2[idx2] 
       idx2 += 1 
     yield lst 


def main(): 
    for s in interleave([1,2,3], ['a','b']): 
     print s 

if __name__ == "__main__": 
    main() 

其基本思想是將輸出映射到(r + b)選擇r個組合。

0

你可以嘗試一些更接近金屬和更優雅(在我看來)迭代不同的可能切片。基本上通過並遍歷所有三個參數到標準切片操作,刪除添加到最終列表中的任何東西。如果您有興趣,可以發佈代碼段。

5

Itertools將不足以能力來處理這個問題,將需要的栓和孔問題

的理解一些位考慮你示例列表

A = [1,2] B = [ 3,4]

有四個孔(len(A) + len(B))其中可以放置元件(銷)

| || || || | 
|___||___||___||___| 

在Python可以表示空時隙作爲None

slots = [None]*(len(A) + len(B)) 

列表的方法可以將來自第二列表中的元素(銷)插入銷被簡單的路的數目可以選擇槽的數量從作爲

len(A) + len(B)çlen(B)

= 4ç孔2

= itertools.combinations(range(0, len(len(A) + len(B)))

可以從第二列表

for splice in combinations(range(0,len(slots)),len(B)): 
    it_B = iter(B) 
    for s in splice: 
     slots[s] = next(it_B) 

被描述爲

| || || || | Slots 
|___||___||___||___| Selected 

    3 4    (0,1) 
    3   4   (0,2) 
    3    4 (0,3) 
     3 4   (1,2) 
     3   4 (1,3) 
      3 4 (2,3) 

現在,每一個這些時隙位置與元件(銷)填充一旦完成後,您只需從第一個列表中的元素(釘)填充剩餘的空插槽

it_A = iter(A) 
    slots = [e if e else next(it_A) for e in slots] 

在開始使用另一個插槽位置的下一次迭代,刷新你的孔

slots = [None]*(len(slots)) 

Python實現了上述方法

def slot_combinations(A,B): 
    slots = [None]*(len(A) + len(B)) 
    for splice in combinations(range(0,len(slots)),len(B)): 
     it_B = iter(B) 
     for s in splice: 
      slots[s] = next(it_B) 
     it_A = iter(A) 
     slots = [e if e else next(it_A) for e in slots] 
     yield slots 
     slots = [None]*(len(slots)) 

和O/P從以上實施

list(slot_combinations(A,B)) 
[[3, 4, 1, 2], [3, 1, 4, 2], [3, 1, 2, 4], [1, 3, 4, 2], [1, 3, 2, 4], [1, 2, 3, 4]] 
+0

這裏是一個懶惰的(它使用生成器insead如果子列表)解決方案栓和孔問題:['interleave_where()'](http://ideone.com/mI4C36)。 – jfs 2013-03-09 07:06:11

+0

啊,我們剛剛得到完整的實現,而不是提示。尼斯。 – nneonneo 2013-03-09 07:23:13

+0

很好的解釋。你可能剛剛說過,我的問題是沒有提供實現的情況下的掛鉤和漏洞問題。在我接受你的答案之前,你可以對它進行校對(我認爲在解釋中有一些錯別字,不應該是= itertools.combinations(範圍(0,len(A)+ len(B)),2)'?)併爲「釘和洞」問題提供前提?我試過谷歌搜索,但只發現「廣場釘和圓孔」的問題或類似的東西。如果你提供了一個很好的前提,我甚至會建議你編輯實現部分,但這是你的選擇。 – crzrcn 2013-03-09 14:51:36