2013-05-08 85 views
3

我有任意長度的列表列表。滿足任意長度列表列表中的條件

例如:

a = [[3,17,19,4],[4,18,10,1],[11,15,13],[7,9,12,16]] 

嵌套的水平被限制在該深度。

我想查找所有列表,其第一個元素來自第一個內部列表,第二個元素來自第二個內部列表,等等,這樣這個新列表的元素都增加了。

根據給出的例子,[4,10,11,12]就是這樣一個列表。

我在努力,我希望解決方案是通用的,而不管有多少內部列表。

如果我得到了保障四個內部名單,我能天真地代碼:

for w in a[0]: 
    for x in a[1]: 
     for y in a[2]: 
      for z in a[3]: 
       if w < x < y < z: 
        print [w,x,y,z] 

但是,如果我添加了一個第五內部列表,或者刪除上面的第四內部列表,我的運氣。

無論主列表中有多少個內部列表,我如何生成所有單調遞增的「子列表」?

回答

3
def combine(lists, peak=None): 
    if not lists: 
    yield [] 
    else: 
    for i in lists[0]: 
     if peak is None or i > peak: 
     for tail in combine(lists[1:], i): 
      yield [ i ] + tail 

for x in combine([[3,17,19,4],[4,18,10,1],[11,15,13],[7,9,12,16]]): print x 

[3, 4, 11, 12] 
[3, 4, 11, 16] 
[3, 4, 15, 16] 
[3, 4, 13, 16] 
[3, 10, 11, 12] 
[3, 10, 11, 16] 
[3, 10, 15, 16] 
[3, 10, 13, 16] 
[4, 10, 11, 12] 
[4, 10, 11, 16] 
[4, 10, 15, 16] 
[4, 10, 13, 16] 
1

如果性能不是問題,您可以使用itertools.product並遍歷所有可能性,例如,

from itertools import product 

def is_increasing(seq): 
    return all(x < y for x,y in zip(seq[:-1], seq[1:])) 

之後

>>> a = [[3,17,19,4],[4,18,10,1],[11,15,13],[7,9,12,16]] 
>>> [k for k in product(*a) if is_increasing(k)] 
[(3, 4, 11, 12), (3, 4, 11, 16), (3, 4, 15, 16), 
(3, 4, 13, 16), (3, 10, 11, 12), (3, 10, 11, 16), 
(3, 10, 15, 16), (3, 10, 13, 16), (4, 10, 11, 12), 
(4, 10, 11, 16), (4, 10, 15, 16), (4, 10, 13, 16)] 

[關於性能的評論是不是因爲itertools.product本身是緩慢的,只是如果你這樣說,你必須每一種可能性搜索過,即使你可以有使用更智能的算法排除此問題。]

相關問題