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

Voici la question:

Donnée une liste d'éléments en Python, comment pourrais-je aller pour obtenir toutes les combinaisons possibles des éléments?

il y a plusieurs questions similaires sur ce site, qui suggèrent d'utiliser des itértools.combiner, mais qui retourne uniquement 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 retourne uniquement les éléments dans un ordre strict, pas de retour (2, 1), (3, 2), (3, 1), (2, 1, 3), (3, 1, 2), (2, 3, 1), et (3, 2, 1). Est-il une solution de contournement? Je n'arrive pas à trouver quoi que ce soit.

21
demandé sur Minas Abovyan 2013-07-02 23:22:10

7 réponses

Utiliser 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 les 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)
>>> 
31
répondu Ashwini Chaudhary 2017-08-10 20:06:37

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
répondu saimadhu.polamuri 2015-10-11 05:00:25

vous cherchez itertools.permutations à la place?

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)

à Partir de 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 y a 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 :

Dans les mathématiques une combinaison est une manière de sélectionner plusieurs choses d'un grand groupe, où (contrairement aux permutations) l'ordre n'a pas d'importance.

6
répondu Sukrit Kalra 2013-07-02 19:29:07

itertools.permutations va être ce que vous voulez. Par définition mathématique, l'ordre n'a pas d'importance pour combinations, ce qui signifie (1,2) est considéré comme identique à l' (2,1). Alors qu'avec permutations, chaque ordre distinct compte comme une permutation unique, donc (1,2) et (2,1) sont complètement différents.

2
répondu Brien 2013-07-02 19:23:19

Voici une solution sans itertools

permet D'abord de définir une translation entre un vecteur indicateur de 0 et 1s et une sous-liste (1 si l'élément se trouve dans la sous-liste)

def indicators2sublist(indicators,arr):
   return [item for item,indicator in zip(arr,indicators) if int(indicator)==1]

ensuite, bien définir un mapping à partir d'un nombre entre 0 et 2^n-1 à la représentation de son vecteur binaire (en utilisant la chaîne de caractères format fonction) :

def bin(n,sz):
   return ('{d:0'+str(sz)+'b}').format(d=n)

Tout ce qu'il nous reste à faire, c'est itérer tous les numéros possibles, et 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
répondu Uri Goren 2016-11-06 13:51:19

je suppose que vous voulez toutes les combinaisons possibles comme des "ensembles" de valeurs. Voici un morceau de code que j'ai écrit qui pourrait 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 exemple:

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
répondu Shashank Singh 2016-07-21 23:46:11

j'ai juste pensé que j'avais mis ça de côté car je ne pouvais pas régler tous les problèmes possibles et en gardant à l'esprit que je n'ai que les connaissances les plus rudimentaires quand il s'agit de python et qu'il y a probablement une solution beaucoup plus élégante...(veuillez également excuser les mauvais noms des variables

essais = [1, 2, 3]

testing2= [0]

n = -1

def testingSomethingElse (number):

try:

    testing2[0:len(testing2)] == testing[0]

    n = -1

    testing2[number] += 1

except IndexError:

    testing2.append(testing[0])

while 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]

je suis parti avec == 4 parce que je travaille avec des entiers mais vous pouvez avoir à modifier cela en conséquence...

-1
répondu Matt Slap 2017-05-13 22:16:08