Voici la question:
Étant donné une liste d'éléments en Python, comment pourrais-je passer pour obtenir toutes les combinaisons possibles des éléments?
Plusieurs questions similaires sur ce site suggèrent d'utiliser itertools.com, mais ne renvoient qu'un sous-ensemble de ce dont j'ai besoin:
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)
Comme vous le voyez, il ne renvoie que les éléments dans un ordre strict, sans renvoyer (2, 1), (3, 2), (3, 1), (2, 1, 3), (3, 1, 2), ( 2, 3, 1) et (3, 2, 1). Y at-il une solution de contournement qui? Je n'arrive pas à trouver quoi que ce soit.
Utilisez 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)
....
aide sur 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)
>>>
Vous pouvez générer toutes les combinaisons d'une liste en python en utilisant ce code simple
import itertools
a = [1,2,3,4]
for i in xrange(1,len(a)+1):
print list(itertools.combinations(a,i))
Résultat:
[(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)]
Recherchez-vous itertools.permutations
à la place?
De 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)
Exemple de code:
>>> 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)
Sur Wikipedia, la différence entre les permutations et les combinaisons:
Permutation:
De manière informelle, une permutation d'un ensemble d'objets est un arrangement de ces objets dans un ordre particulier. Par exemple, il existe six permutations de l'ensemble {1,2,3}, à savoir (1,2,3), (1,3,2), (2,1,3), (2,3,1) , (3,1,2) et (3,2,1).
Combinaison :
En mathématiques, une combinaison est une façon de sélectionner plusieurs éléments d'un groupe plus grand, où (contrairement aux permutations), l'ordre n'a pas d'importance.
Commençons par définir une traduction entre un vecteur indicateur de 0
et 1
s et une sous-liste (1
si l'élément est dans la sous-liste)
def indicators2sublist(indicators,arr):
return [item for item,indicator in Zip(arr,indicators) if int(indicator)==1]
Ensuite, définissez correctement un mappage entre un nombre compris entre 0
et 2^n-1
et sa représentation vectorielle binaire (à l'aide de la fonction format
de la chaîne):
def bin(n,sz):
return ('{d:0'+str(sz)+'b}').format(d=n)
Tout ce qui nous reste à faire est d’itérer tous les nombres possibles et d’appeler indicators2sublist
def all_sublists(arr):
sz=len(arr)
for n in xrange(0,2**sz):
b=bin(n,sz)
yield indicators2sublist(b,arr)
itertools.permutations
va être ce que vous voulez. Selon la définition mathématique, l'ordre n'a pas d'importance pour combinations
, ce qui signifie que (1,2)
est considéré identique à (2,1)
. Alors que avec permutations
, chaque ordre distinct compte comme une permutation unique, donc (1,2)
et (2,1)
sont complètement différents.
Je suppose que vous voulez que toutes les combinaisons possibles soient des «ensembles» de valeurs. Voici un morceau de code que j'ai écrit qui pourrait aider à vous donner une idée:
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
Voici un échantillon:
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])]
Je pense que cela a n! la complexité du temps, alors soyez prudent. Cela fonctionne mais peut ne pas être le plus efficace