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.
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)
>>>
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)]
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.
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.
Voici une solution sans itertools
permet D'abord de définir une translation entre un vecteur indicateur de 0
et 1
s 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)
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
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...