web-dev-qa-db-fra.com

Générer toutes les combinaisons d'une liste en python

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.

22
Minas Abovyan

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)
>>> 
33
Ashwini Chaudhary

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)]
9
saimadhu.polamuri

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.

6
Sukrit Kalra

Voici une solution sans outils informatiques

Commençons par définir une traduction entre un vecteur indicateur de 0 et 1s 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)
2
Uri Goren

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.

2
Brien

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

0
Shashank Singh