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