web-dev-qa-db-fra.com

Python - Comment générer tout moyen possible une liste de 12 éléments peut être divisé en 3 listes de n'importe quelle taille (y compris vide)

J'ai 2 listes, une avec 12 éléments et une avec 3 sous-listes.

a = [1,2,3,4,5,6,7,8,9,10,11,12]
b = [[],[],[]]

J'ai besoin d'écrire Python code qui générera toutes les méthodes possibles dans lesquelles les 12 éléments de A peuvent être distribués dans les sous-listes de b. Il y a 3 ^ 12 (un peu plus d'un demi-million ) Combinaisons. Par exemple, certaines combinaisons possibles seraient les suivantes:

[[1,2,3,4,5,6,7,8,9,10,11,12],[],[]]
[[1,2,3,4],[5,6],[7,8,9,10,11,12]]
[[1,4,12],[2,3,9,11],[5,6,7,8,10]]

L'ordre n'a pas d'importance dans les listes. J'ai essayé d'utiliser des fonctions ITERTOOLS telles que la permutation et la combinaison, mais elles ne semblent pas faire ce que je cherche. J'ai essayé

    buildings = list(range(1,13)) #assign each building a unique id
    building_arrangement = [list(range(1,13)),[],[]] # quarries, factories, markets
    all_arrangements.append(building_arrangement)
    
    combos = itertools.combinations(buildings, 3)
    
    for combo in combos:
        print(combo)

Mais ce qui précède semble obtenir la combinaison de chacun des 12 chiffres individuellement par opposition au traitement des 12 numéros complets en tant que jeu et à la recherche de chaque ensemble unique pouvant être effectué. Je ne sais pas si cela peut être fait via des bibliothèques préexistantes, iTertools ne semble pas fournir un moyen de le faire à partir de ce que je peux voir dans la documentation, mais je pourrais me tromper.

2
James O'Neill

Notez que chaque combinaison peut être codée par un numéro M-ary, où M est le nombre de sublistes. Itération sur tous les numéros N-Dickit M-ary (où n est le nombre d'éléments) fera le tour:

N = 12
M = 3

for n in range(N**M):
    combination = [[] for __ in range(M)]
    for i in range(N):
        combination[n // 3**i % 3].append(i)
    print(combination)
1
fanfly

Vous pouvez utiliser une fonction de générateur récursive:

a = [1,2,3,4,5,6,7,8,9,10,11,12]
def groups(d, n, c = []):
   if not d and len(c) == n:
      yield c
   Elif d:
      for i, j in enumerate(d):
         if not c or len(c) + 1 <= n:
            yield from groups(d[:i]+d[i+1:], n, c+[[j]])
         if c:
            yield from groups(d[:i]+d[i+1:], n, c[:-1]+[[*c[-1], j]])

def results(d, n):
    s = []
    for i in groups(d, n):
       if (k:=[*map(sorted, i)]) not in s:
          yield k
          s.append(k)

r = results(a, 3)
for _ in range(10): #first 10 results
   print(next(r)) 

Sortir:

[[1], [2], [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]]
[[1], [2, 3], [4, 5, 6, 7, 8, 9, 10, 11, 12]]
[[1], [2, 3, 4], [5, 6, 7, 8, 9, 10, 11, 12]]
[[1], [2, 3, 4, 5], [6, 7, 8, 9, 10, 11, 12]]
[[1], [2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
[[1], [2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12]]
[[1], [2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12]]
[[1], [2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12]]
[[1], [2, 3, 4, 5, 6, 7, 8, 9, 10], [11, 12]]
[[1], [2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [12]]  
1
Ajax1234

Aussi pourquoi ne pas essayer recettes iTertool , powerset()

pip install more-itertools

Puis,

from more_itertools import recipes

a = [1,2,3,4,5,6,7,8,9,10,11,12]
tuples = recipes.powerset(a)
for Tuple in tuples:
  print(Tuple)

Cela créera tous les ensembles possibles du déménier donné. Vous pouvez la diviser en listes de 3 en utilisant une fonction différente.

0
Nishan