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.
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)
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]]
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.