2015-08-25 2 views
1

Étant donné une liste ordonnée de 'n' éléments, je souhaite découper la liste pour générer toutes les permutations distinctes de sous-listes une seule fois, tout en maintenant l'ordre de la liste Composition de ma liste d'entrée. (Ce n'est pas la même chose que de calculer toutes les combinaisons possibles de sous-listes possibles à partir de ma liste d'entrées).Générer de manière récursive des compositions à partir d'une liste ordonnée

Par exemple, la liste d'entrée donné [A,B,C,D], ma sortie serait les 8 listes imbriquées suivantes:

[[A,B,C,D]], [[A,B,C],[D]], [[A,B],[C,D]], [[A,B],[C],[D]], [[A],[B,C],[D]], [[A],[B],[C,D]], [A,[B,C,D]], [[A],[B],[C],[D]]. 

Dessiner un arbre de permutations possibles suggère que ce problème se prêterait à un algorithme récursif, mais je Je ne sais pas comment implémenter ceci en Python pour une vitesse et une efficacité maximales, et je serais très reconnaissant pour vos conseils et vos conseils.

+0

Vous avez manqué [[A], [BCD]]. Le nombre de résultats possibles n'est-il pas '2^(n - 1)' pour les listes d'éléments 'n'? Vous pouvez représenter les séparations comme un nombre binaire avec des bits 'n - 1'; chaque bit représente un écart. –

+1

https://fr.wikipedia.org/wiki/Composition_(combinatoires) –

+0

Merci d'avoir remarqué cela si rapidement. Question originale éditée de manière appropriée. – Dave

Répondre

3
def composition(seq): 
    seq = tuple(seq) 
    for i in range(2**(len(seq)-1)): 
     result = [[seq[0]]] 
     for j in range(len(seq)-1): 
      if i & (1<<j): 
       result.append([seq[j+1]]) 
      else: 
       result[-1].append(seq[j+1]) 
     yield result 

if __name__=="__main__": 
    from pprint import pprint 
    pprint(list(composition('ABCD'))) 

Référence: https://en.wikipedia.org/wiki/Composition_(combinatorics)

+0

Génial! Merci beaucoup Rob. – Dave