1
votes

Comment générer toutes les combinaisons distinctes (où les éléments d'entrée sont répétés) en Python (en utilisant Itertools)?

J'ai un ensemble de nombres [1, 2, 4, 1] . Maintenant, je veux générer toutes les combinaisons possibles à partir de cet ensemble de taille k (exemple k = 3). Tous les ensembles de sortie générés ne doivent pas être dupliqués

Exemple: [1, 2, 1] et [2, 1, 1] sont les mêmes ensembles mais ils devraient ne pas être sélectionné. Un seul d'entre eux devrait apparaître. Est-il possible d'utiliser des combinaisons d'itertools en Python?

[(0, -1, -4), (-1, -1, -4), (-1, 1, -4), (0, 2, -1), (-1, 0, 2), (-1, 2, -4), (0, 1, 2), (2, -1, -4), (-1, 0, -1), (0, 1, -4), (1, 2, -4), (-1, 0, 1), (-1, 1, 2), (0, 2, -4), (-1, 1, -1), (-1, 2, -1), (1, 2, -1), (0, 1, -1), (-1, 0, -4), (1, -1, -4)]

J'ai essayé d'utiliser itertools.product mais cela ne fonctionne pas et l'utilisation de combinaisons d'itertools génère des doublons

J'ai essayé d'utiliser itertools.combinations print ([p for p in set (itertools.combinations (x, r = 3))])

Si je donne l'entrée suivante

  x =  [-1, 0, 1, 2, -1, -4]

La sortie générée pour r = 3 est

import itertools
x = [1, 2, 1]
print([p for p in itertools.product(x, repeat=3)])

(-1, 0, 1) et ( 0, 1, -1) sont des ensembles en double avec les mêmes combinaisons. Je ne sais pas comment surmonter cela.


0 commentaires

3 Réponses :


0
votes

Vous pouvez utiliser set datatype de python pour supprimer ces doublons car les ensembles ne contiennent que les combinaisons uniques:

{(-4, -1, -1),
 (-4, -1, 0),
 (-4, -1, 1),
 (-4, -1, 2),
 (-4, 0, 1),
 (-4, 0, 2),
 (-4, 1, 2),
 (-1, -1, 0),
 (-1, -1, 1),
 (-1, -1, 2),
 (-1, 0, 1),
 (-1, 0, 2),
 (-1, 1, 2),
 (0, 1, 2)}

Sortie:

unique_permutations = set(tuple(sorted(t)) for t in permutations)

Ensuite, utilisez peut utiliser la ligne suivante:

[(0, 1, 2),
 (-1, 1, -1),
 (-1, 2, -1),
 (0, -1, -4),
 (-1, -1, -4),
 (-1, 1, -4),
 (-1, 2, -4),
 (2, -1, -4),
 (1, 2, -4),
 (-1, 0, 1),
 (1, 2, -1),
 (-1, 0, -4),
 (-1, 0, 2),
 (-1, 0, -1),
 (-1, 1, 2),
 (0, 2, -4),
 (0, 2, -1),
 (0, 1, -4),
 (1, -1, -4),
 (0, 1, -1)]

Sortie :

import itertools as it
x = [-1, 0, 1, 2, -1, -4]

permutations = [p for p in set(it.combinations(x, r=3))]
print(permutations)


0 commentaires

0
votes

Pourquoi ne pas obtenir les combinaisons et ne prendre que les uniques en saisissant un dictionnaire avec frozenset résultat des combinaisons. Cela utilisera uniquement des générateurs jusqu'à la création du dictionary .

combs1, combs2 = itertools.tee(itertools.combinations(x, r=3))
res = list(dict(zip(map(frozenset, combs1), combs2)).values())


0 commentaires

0
votes

Ceux-ci sont appelés multisets , et nous pouvons facilement obtenir les combinaisons de ceux-ci avec le module sympy .

x = [-1, 0, 1, 2, -1, -4]
list(multiset_combinations(x, 3))
[[-4, -1, -1],
    [-4, -1, 0],
    [-4, -1, 1],
    [-4, -1, 2],
    [-4, 0, 1],
    [-4, 0, 2],
    [-4, 1, 2],
    [-1, -1, 0],
    [-1, -1, 1],
    [-1, -1, 2],
    [-1, 0, 1],
    [-1, 0, 2],
    [-1, 1, 2],
    [0, 1, 2]]

Et voici l'exemple de @EdedkiOkoh:

from sympy.utilities.iterables import multiset_combinations

list(multiset_combinations([1, 2, 4, 1], 3))
[[1, 1, 2], [1, 1, 4], [1, 2, 4]]


0 commentaires