我有一个任意长度的数字列表。
例如:
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]
但是,如果我添加第五个内部列表,或删除上面的第四个内部列表,我运气不好。
无论主列表中有多少内部列表,我如何生成所有单调增加的“子列表”?
答案 0 :(得分: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 :(得分: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
本身很慢,只是如果你这样做,你必须搜索所有可能性,即使你可以用更智能的算法更早地排除它。 ]