Создание всех комбинаций списка в python
Здесь вопрос:
Учитывая список элементов в Python, как мне пройти, чтобы получить все возможные комбинации элементов?
На этом сайте есть несколько похожих вопросов, которые предлагают использовать itertools.combine, но это возвращает только часть того, что мне нужно:
stuff = [1, 2, 3]
for L in range(0, len(stuff)+1):
for subset in itertools.combinations(stuff, L):
print(subset)
()
(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 3)
(1, 2, 3)
Как вы видите, он возвращает только элементы в строгом порядке, а не возвращает (2, 1), (3, 2), (3, 1), (2, 1, 3), (3, 1, 2), (2, 3, 1) и (3, 2, 1). Есть ли какое-то обходное решение? Кажется, я ничего не могу придумать.
Ответы
Ответ 1
Используйте itertools.permutations
:
>>> import itertools
>>> stuff = [1, 2, 3]
>>> for L in range(0, len(stuff)+1):
for subset in itertools.permutations(stuff, L):
print(subset)
...
()
(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
....
help itertools.permutations
:
permutations(iterable[, r]) --> permutations object
Return successive r-length permutations of elements in the iterable.
permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)
>>>
Ответ 2
Вы можете сгенерировать все комбинации списка в python, используя этот простой код
import itertools
a = [1,2,3,4]
for i in xrange(1,len(a)+1):
print list(itertools.combinations(a,i))
Результат:
[(1,), (2,), (3,), (4,)]
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]
[(1, 2, 3, 4)]
Ответ 3
Вы ищете itertools.permutations
вместо этого?
Из help(itertools.permutations)
,
Help on class permutations in module itertools:
class permutations(__builtin__.object)
| permutations(iterable[, r]) --> permutations object
|
| Return successive r-length permutations of elements in the iterable.
|
| permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)
Пример кода:
>>> from itertools import permutations
>>> stuff = [1, 2, 3]
>>> for i in range(0, len(stuff)+1):
for subset in permutations(stuff, i):
print(subset)
()
(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
(3, 2)
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)
Из Википедии разница между перестановками и комбинациями:
Перестановка:
Неформально, перестановка множества объектов - это расположение этих объектов в определенном порядке. Например, существует шесть перестановок множества {1,2,3}, а именно (1,2,3), (1,3,2), (2,1,3), (2,3,1), (3,1,2) и (3,2,1).
Комбинация:
В математике комбинация - это способ выбора нескольких вещей из большей группы, где порядок (в отличие от перестановок) не имеет значения.
Ответ 4
itertools.permutations
будет тем, что вы хотите. По математическому определению порядок не имеет значения для combinations
, что означает, что (1,2)
считается идентичным (2,1)
. Если permutations
, каждое отдельное упорядочение считается уникальной перестановкой, поэтому (1,2)
и (2,1)
полностью различаются.
Ответ 5
Вот решение без itertools
Сначала давайте определим перевод между вектором-индикатором 0
и 1
и под-списком (1
, если элемент находится в подсписке)
def indicators2sublist(indicators,arr):
return [item for item,indicator in zip(arr,indicators) if int(indicator)==1]
Далее, определите отображение из числа между 0
и 2^n-1
в его двоичное векторное представление (используя функцию string format
):
def bin(n,sz):
return ('{d:0'+str(sz)+'b}').format(d=n)
Все, что нам осталось сделать - это перебрать все возможные числа и называть indicators2sublist
def all_sublists(arr):
sz=len(arr)
for n in xrange(0,2**sz):
b=bin(n,sz)
yield indicators2sublist(b,arr)
Ответ 6
Я предполагаю, что вы хотите, чтобы все возможные комбинации были "наборами" значений. Вот фрагмент кода, который я написал, который может помочь вам понять:
def getAllCombinations(object_list):
uniq_objs = set(object_list)
combinations = []
for obj in uniq_objs:
for i in range(0,len(combinations)):
combinations.append(combinations[i].union([obj]))
combinations.append(set([obj]))
return combinations
Вот пример:
combinations = getAllCombinations([20,10,30])
combinations.sort(key = lambda s: len(s))
print combinations
... [set([10]), set([20]), set([30]), set([10, 20]), set([10, 30]), set([20, 30]), set([10, 20, 30])]
Я думаю, что у этого есть n! сложность времени, поэтому будьте осторожны. Это работает, но может быть не самым эффективным
Ответ 7
просто подумал, что я поместил бы это там, так как я не мог улавливать КАЖДЫЙ возможный результат и имея в виду, что у меня есть только самые базовые знания, когда дело доходит до python, и там, вероятно, гораздо более элегантное решение... (также извините имена бедных переменных
testing = [1, 2, 3]
testing2 = [0]
n = -1
def testingSomethingElse (число):
try:
testing2[0:len(testing2)] == testing[0]
n = -1
testing2[number] += 1
except IndexError:
testing2.append(testing[0])
а True:
n += 1
testing2[0] = testing[n]
print(testing2)
if testing2[0] == testing[-1]:
try:
n = -1
testing2[1] += 1
except IndexError:
testing2.append(testing[0])
for i in range(len(testing2)):
if testing2[i] == 4:
testingSomethingElse(i+1)
testing2[i] = testing[0]
я ушел с == 4, потому что я работаю с целыми числами, но вам, возможно, придется изменить это соответственно...