2013-11-03 2 views
0

Я искал вокруг, но я не совсем уверен, как это сказать. У меня есть список списков, и каждый внутренний список имеет определенный размер, k. Я хочу создать список комбинаций с размером k + 1. Так, например, если я начну с:Generate Списки участников в выбранном размере python

[[1,2],[1,3],[3,4]] 

Я хочу, чтобы создать список:

[[1,2,3],[1,3,4]] 

Где списки сколь угодно долго. Я думаю, что мне нужно будет использовать функцию комбинаций из библиотеки itertools и, возможно, установить с помощью объединений. Я просто застрял в том, как это сделать эффективно.

Любая помощь очень ценится!

Редактировать: Мне нужно уточнить. Я только пытаюсь создать списки длины k + 1 (3 в этом случае), где два из исходных списков объединены. Поэтому, если они были наборами, я хочу получить только результирующие множества длины k + 1, когда мы возьмем объединение двух множеств.

+0

, что случилось с комбинациями '(1,2,4) и' (2,3,4) '? – roippi

+0

Извините, я не сделал это очень ясно. Поэтому я хочу создать только списки, которые могут состоять из двух списков. Итак, (1,2) и (1,3) вместе составляют (1,2,3). И (1,3) и (3,4) составляют (1,3,4). Итак, если они были множествами, то только объединение двух множеств, имеющих длину 3. Имеет ли это смысл? – Championcake

ответ

1

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, сортируя их для хорошей меры.

+0

Это работает только в том случае, если списки сортируются по отдельности для начала. – roippi

+0

Отлично. Это set(). Union (* x) - это то, что ускользало от меня. Я не рассматривал использование splat! Спасибо огромное! – Championcake

+0

@roippi: не могли бы вы объяснить? – DSM

1

Я не совсем уверен, что ожидаемый выход, потому что не хватает несколько комбинаций, но попробовать это:

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)

+0

Я не пытаюсь сгенерировать все комбинации, только комбинации длины k + 1, когда сливаются два списка. Извините, я думаю, что я изложил оригинальный вопрос ужасно. Я отредактирую его. – Championcake

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

Спасибо. На данный момент я не уверен, что алгоритм требует стабильности или нет. Я ценю, что вы тратите время на это, хотя мне это очень может понадобиться! – Championcake

+1

'list (OrderedDict.fromkeys (source))' мой любимый способ подделать 'OrderedSet'. Хотелось бы, чтобы они дали нам настоящую. – DSM

+0

@ DSM да, согласен. Мне не нужно заботиться о производительности, но давайте, насколько более интуитивно понятно, просто иметь правильный 'OrderedSet'. Ах хорошо. – roippi

Смежные вопросы