生成元素小于或等于给定列表的列表

时间:2018-06-25 11:32:29

标签: python list

解决以下问题的最有效方法是什么?

给出一个列表A,找到所有列表B,这样对于范围(len(A))中的i:B [i] <= A [i]。我期望的示例:

#Input
A = [1,2,0]
#Output
B = [[0,0,0],
     [1,0,0],
     [1,1,0],
     [1,2,0],
     [0,1,0],
     [0,2,0]]

谢谢!

4 个答案:

答案 0 :(得分:7)

您可以使用itertools.product轻松完成此操作

>>> from itertools import product
>>> A
[1, 2, 0]
>>> B = list(product(*[list(range(e+1)) for e in A]))
>>> B
[(0, 0, 0), (0, 1, 0), (0, 2, 0), (1, 0, 0), (1, 1, 0), (1, 2, 0)]
>>> 

如果要将o / p作为列表列表,请将元组转换为列表

>>> B = [list(e) for e in B]
>>> B
[[0, 0, 0], [0, 1, 0], [0, 2, 0], [1, 0, 0], [1, 1, 0], [1, 2, 0]]
>>> 

如果您不想使用itertools.product,则可以使用product的自定义实现

>>> B = [[]]; 
>>> for t in [range(e+1) for e in A]:
...     B = [x+[y] for x in B for y in t]
... 
>>> B
[[0, 0, 0], [0, 1, 0], [0, 2, 0], [1, 0, 0], [1, 1, 0], [1, 2, 0]]
>>> 

答案 1 :(得分:1)

这是一个非常聪明的解决方案,无需使用itertools,而是使用递归函数调用。无论输入列表的大小如何,它都可以工作:

A = [1,2,0]

def compute(A, B=[], n=0):
    for i in range(A[n]+1):
        A[n] = i
        if A not in B: B.append(A[:])
        if n+1 < len(A): compute(A, B, n+1)  # recursive call here
    return sorted(B)

B = compute(A)

print(B)
# [[0, 0, 0], [0, 1, 0], [0, 2, 0], [1, 0, 0], [1, 1, 0], [1, 2, 0]]

答案 2 :(得分:0)

我想您首先可以生成这些数字的所有唯一组合:

>>> import itertools
>>> A = [1,2,0]
>>> combs = set(itertools.combinations(itertools.chain(*(range(col+1) for col in A)), len(A)))
>>> combs
{(0, 1, 1), (0, 2, 0), (1, 1, 0), (1, 2, 0), (0, 0, 2), (0, 1, 2), (1, 0, 0), (0, 0, 1), (1, 0, 1), (1, 1, 2), (0, 0, 0), (0, 1, 0), (1, 0, 2)}

然后选择符合您条件的内容:

>>> sorted(comb for comb in combs if all(comb[i] <= x for i, x in enumerate(A)))
[(0, 0, 0), (0, 1, 0), (0, 2, 0), (1, 0, 0), (1, 1, 0), (1, 2, 0)]

但是,这比使用itertools.product效率低得多,因为它必须事先生成所有组合,并在最后排序以保持顺序。

答案 3 :(得分:0)

这也有效:

A = [1,2,0]

answers = [[] for element in A]
answers[0] = [[number,] for number in range(A[0]+1)]

for i in range(len(A)-1):
    for possibility in answers[i]:
        for valid_number in range(A[i+1]+1):
            answers[i+1].append(possibility + [valid_number, ])

your_answer = answers[-1]

它可能以更紧凑的方式编写。