简体   繁体   English

如何生成此特定列表列表

[英]How to produce this specific list of lists

I have a bit of a complicated problem. 我有一个复杂的问题。 I'm trying to make a function which takes in a list of 0s and 1s and returns a list of lists. 我正在尝试创建一个函数,它接受0和1的列表并返回列表列表。 It's easiest if I just show an example 如果我只是展示一个例子,这是最简单的

input : 输入

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

output : 输出

[[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]]

Another example 另一个例子

input : 输入

[1,0,1]

output : 输出

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

I have a solution right now, where I first produce all the the combinations and then filters out the ones that are not allowed. 我现在有一个解决方案,我首先生成所有组合,然后筛选出不允许的组合。 But this demands massive amount of memory so I'm looking for a better solution. 但这需要大量的内存,所以我正在寻找更好的解决方案。

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

You can get a list of the indices to mutate, then use itertools.product to generate all the possible variations. 您可以获取要变异的索引列表,然后使用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]]

Idea: Get indices. 想法:获取指数。 Then take all subsets of indices to generate sublists to add to result 然后获取所有索引子集以生成要添加到结果的子列表

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]]

Use itertools.permutations , and just prepend a 1 to each of them. 使用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])

If you'd rather write a single expression rather than a generator function, its just 如果您更愿意编写单个表达式而不是生成器函数,那么它就是

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))))

Using itertools.product and a generator: 使用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))]

Then list(get_combinations([0, 0, 0, 1, 0, 1])) prints 然后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]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM