如何生成列表的特定列表

时间:2019-08-06 13:54:17

标签: python list

我有一个复杂的问题。我正在尝试制作一个函数,该函数接受0和1的列表并返回列表的列表。如果我举个例子,那是最简单的

输入

[0,0,0,1,0,1]

输出

[[0,0,0,0,0,0,0],[1,0,0,0,1,0,0],[1,0,0,0,1,0,1],[1,0,0,0,0,0,1],[1,0,0,0,0,0,0]]

另一个例子

输入

[1,0,1]

输出

[[0,0,0,0],[1,1,0,0],[1,0,0,1],[1,1,0,1],[1,0,0,0]]

我现在有一个解决方案,我首先生成所有组合,然后过滤掉不允许的组合。但这需要大量的内存,因此我正在寻找更好的解决方案。

def func(input):
    A = list(itertools.product(range(2), repeat=int(len(input)+1)))

    # Filters out all the lists which have first element equal to 0 
    #  and 1s anywhere else 
    A = [item for item in A if not (item[0] == 0 \
                    and sum(item) >= 1 or item[A.index(item)+1] == 1) ]

    # Filter out all lists which has 1s at places the input does not have
    A = [item for item in action_space if not \
                    sum(np.bitwise_and(np.bitwise_xor(item[1:], \
                    self.adj_mat[node.get_node_nr()]),item[1:])) > 0]

    return A

4 个答案:

答案 0 :(得分:2)

您可以获取要突变的索引列表,然后使用itertools.product生成所有可能的变体。

from itertools import product

def func(l):
    indicies = [i for i, x in enumerate(l, start=1) if x]
    prod = product([0, 1], repeat=len(indicies))
    yield [0] * (len(l) + 1)
    for variation in prod:
        temp = [1, *l]
        for index, value in zip(indicies, variation):
            temp[index] = value
        yield temp

print(list(func([0,0,0,1,0,1])))
# [[0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 1, 0, 1]]
print(list(func([1,0,1])))
# [[0, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 1], [1, 1, 0, 0], [1, 1, 0, 1]]

答案 1 :(得分:1)

想法:获取索引。然后使用索引的所有子集来生成要添加到结果中的子列表

from itertools import chain, combinations

def powerset(iterable):
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

lst = [0,0,0,1,0,1]
indices = [i for i, x in enumerate(lst) if x == 1]
result = [[0] * (len(lst)+1)]
for element in powerset(s):
    new_element = [[0] * (len(lst)+1)]
    new_element[0][0] = 1
    for pos in element:
        new_element[0][pos+1] = int(1)
    result.extend(new_element)

print(result) # [[0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 1, 0, 1]]

答案 2 :(得分:0)

使用itertools.permutations,然后在每个数字前面加上1。

from itertools import permutations


def augment(xs):
    yield [0] + [0 for _ in xs]
    for x in permutations(xs):
        yield [1] + list(x)


out = list(augment([1,0,1])

如果您只想编写一个表达式而不是生成器函数,那么它只是

from itertools import chain, permutations

xs = [1, 0, 1]
out = list(chain([[0] + [0 for _ in xs]], ([1] + list(x) for x in permutations(xs))))

答案 3 :(得分:0)

使用itertools.product和生成器:

def get_combinations(lst):
    yield [0]*(len(lst)+1)
    idxs = [idx for idx, x in enumerate(lst) if x]
    for vals in product(*[[0, 1]]*2):
        vals_i = iter(vals)
        yield [1] + [0 if idx not in idxs else next(vals_i) for idx in range(len(lst))]

然后打印list(get_combinations([0, 0, 0, 1, 0, 1]))

[[0, 0, 0, 0, 0, 0, 0],
 [1, 0, 0, 0, 0, 0, 0],
 [1, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 1, 0, 0],
 [1, 0, 0, 0, 1, 0, 1]]