解决以下问题的最有效方法是什么?
给出一个列表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]]
谢谢!
答案 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]
它可能以更紧凑的方式编写。