Генерация объединенных списков заданного размера в python
Я искал вокруг, но я не совсем уверен, как это сформулировать. У меня есть список списков, и каждый внутренний список имеет определенный размер, k. Я хочу создать список комбинаций, которые имеют размер k+1. Например, если я начну с:
[[1,2],[1,3],[3,4]]
Я хочу создать список:
[[1,2,3],[1,3,4]]
Где списки произвольно длинные. Я думаю, мне нужно будет использовать функцию комбинаций из библиотеки itertools и, возможно, наборы с объединениями. Я просто застрял в том, как сделать это эффективно.
Любая помощь очень ценится!
Изменить: мне нужно уточнить. Я только пытаюсь сгенерировать списки длиной k+1 (в данном случае 3), где два оригинальных списка объединены. Поэтому, если бы они были множествами, я хочу получить только результирующие множества длины k + 1, когда мы берем объединение двух множеств.
3 ответа
IIUC, как насчет этого?
>>> from itertools import combinations
>>> lol = [[1,2],[1,3],[3,4]]
>>> k = len(lol[0])
>>> pair_sets = (set().union(*x) for x in combinations(lol,2))
>>> keep = [sorted(x) for x in pair_sets if len(x) == k+1]
>>> keep
[[1, 2, 3], [1, 3, 4]]
set().union(*x)
это просто хороший способ получить объединение произвольной коллекции множеств; здесь мы могли бы одинаково хорошо использовать set(x[0]).union(x[1])
вместо.
Элементы, полученные от pair_sets
наборы, которые выглядят как
>>> pair_sets = list(set().union(*x) for x in combinations(lol,2))
[set([1, 2, 3]), set([1, 2, 3, 4]), set([1, 3, 4])]
а потом мы оставим те, у кого длина k+1
сортируя их по мере необходимости.
Если вам не важен порядок ваших выходных данных, ответ @DSM будет правильным. Тем не менее, если у вас есть входы, такие как [[3,2],[1,3],[7,2]]
и вам нужно сохранить порядок ввода, вам нужно быть более сложным, так как порядок стирается, как только ваши элементы входят в set
,
Я отразлю его код, чтобы вы могли увидеть разницу:
from itertools import combinations, chain
from collections import OrderedDict
lol = [[3,2],[1,3],[7,2]]
k = len(lol[0])
pair_sets = [list(OrderedDict.fromkeys(chain.from_iterable(x))) for x in combinations(li,2)]
keep = [x for x in pair_sets if len(x) == k+1]
keep
[[3, 2, 1], [3, 2, 7]]
Я не совсем уверен относительно вашего ожидаемого результата, потому что в нем не хватает нескольких комбинаций, но попробуйте это:
import itertools
L = [[1,2],[1,3],[3,4]]
print list(itertools.combinations(list(set(itertools.chain.from_iterable(L))), len(L[0])+1))
list(set(itertools.chain.from_iterable(L)))
сгладит список и получит уникальные элементы. Тогда мы получим комбинации этого с длиной первого элемента (k
)