Генерация всех возможных списков путем замены элементов на 0 - PullRequest
0 голосов
/ 30 апреля 2018

Я хотел бы создать из списка все разные списки были 0,1,2,3 ... все элементы заменены на другие Например, если заменяемый элемент равен 0:

L=[1,2,3]
->[1,2,3],[0,2,3],[1,0,3],[1,2,0],[0,0,3],[0,2,0],[1,0,0],[0,0,0]

Пока я пытался, мне удалось сделать то, что я хочу, используя Itertools, но только в случае, когда 1 значение заменяется на 0 Кто-нибудь знает, как это сделать?

Ответы [ 4 ]

0 голосов
/ 30 апреля 2018

Все слишком стараются здесь. Мы хотим, чтобы каждое значение было либо исходным, либо 0 - нам нужны такие пары, как (1,0), (2,0) и (3,0):

>>> from itertools import product, repeat
>>> L = [1, 2, 3]
>>> zip(L, repeat(0))
<zip object at 0x7f931ad1bf08>
>>> list(zip(L, repeat(0)))
[(1, 0), (2, 0), (3, 0)]

и тогда мы можем просто передать это в product:

>>> list(product(*zip(L, repeat(0))))
[(1, 2, 3), (1, 2, 0), (1, 0, 3), (1, 0, 0), (0, 2, 3), (0, 2, 0), (0, 0, 3), (0, 0, 0)]
0 голосов
/ 30 апреля 2018

Это не красиво, но я уверен, что вы можете заставить эту идею работать.

Идея состоит в том, чтобы использовать itertools.combination для получения всех комбинаций индексов для каждой длины, затем мы сглаживаем этот список с помощью itertools.chain ().

Затем мы перебираем этот список списков, присваивая этим индексам символ замены.

import itertools
l = [1,2,3]
replace = 0

indices = list(itertools.chain(*[list(itertools.combinations(list(range(len(l))),z+1)) for z in range(len(l))]))

allcombs = [[l]]
for i in indices:
    l2 = l[:]
    for j in i:
        l2[j] = replace
    allcombs.append(l2)

print(allcombs)

[[[1, 2, 3]], [0, 2, 3], [1, 0, 3], [1, 2, 0], [0, 0, 3], [0, 2 , 0], [1, 0, 0], [0, 0, 0]]

0 голосов
/ 30 апреля 2018

Вы можете использовать рекурсию. Сначала создайте функцию, которая может генерировать полные комбинации для каждого индекса ввода:

def full_combinations(d, current = []):
   if len(d) == len(current):
     yield current
   else:
     yield current
     for i in range(len(d)):
        if len(set(current+[i])) == len(current)+1:
           yield from full_combinations(d, current+[i])

combination_list = list(full_combinations([1, 2, 3]))
new_results = [[0 if c in i else a for c, a in enumerate([1, 2, 3])] for i in combination_list]
full = [a for i, a in enumerate(new_results) if a not in new_results[:i]]

Выход:

[[1, 2, 3], [0, 2, 3], [0, 0, 3], [0, 0, 0], [0, 2, 0], [1, 0, 3], [1, 0, 0], [1, 2, 0]]
0 голосов
/ 30 апреля 2018

Это один из способов использования itertools. Преимущество этого метода в том, что он ленивый.

Новый список создается при каждом __next__ вызове генератора transformer.

В качестве альтернативы, как показано ниже, вы можете вывести все комбинации, вызвав list в функции генератора.

from itertools import combinations, chain

A = [1, 2, 3]

def transformer(x):
    idx = chain.from_iterable(combinations(range(len(x)), i) for i in range(len(x)+1))
    for indices in idx:
        y = x.copy()
        for j in indices:
            y[j] = 0
        yield y

res = list(transformer(A))

print(res)

[[1, 2, 3], [0, 2, 3], [1, 0, 3], [1, 2, 0], [0, 0, 3], [0, 2, 0], [1, 0, 0], [0, 0, 0]]
...