2010-11-16 5 views
4

J'ai une liste de listes. En utilisant itertools, je fais essentiellementpython itertools sauter devant

pour résultat dans le produit ([A, B], [C, D], [E, F, G]): # test de chaque résultat

et le résultat est le produit désiré, chaque résultat contenant un élément de chacune des listes. Mon code teste chacun des résultats élément par élément, en recherchant le premier (et le meilleur) «bon». Il peut y avoir un très grand nombre à tester.

Supposons que je teste le premier résultat 'ACE'. Disons que lorsque je teste le second élément 'C', je trouve que 'ACE' est un mauvais résultat. Il n'est pas nécessaire de tester 'ACF' ou 'ACG'. Je voudrais passer de l'ACE échoué directement à essayer ADE. De toute façon de le faire sans juste jeter les résultats indésirables sur le sol? Si j'implémentais ceci avec des boucles imbriquées, j'essaierais de manipuler les index de boucle for à l'intérieur de la boucle et ce ne serait pas très bien ... mais je veux sauter beaucoup de résultats. Puis-je passer rapidement en revue dans itertools?

+2

Si 'C' est un mauvais résultat, est-ce que ce serait encore un mauvais résultat quand vous arriverez à 'BCE' Est-ce qu'un élément individuel est toujours mauvais ou juste quand il est dans certaines combinaisons? – snapshoe

+0

@Rod. __ever__. – aaronasterling

+0

éléments individuels ne sont pas mauvais, il n'y a que de mauvaises combinaisons d'éléments – Mike

Répondre

1

itertools n'est pas la meilleure façon d'y aller avec le souci que vous avez.

Si vous n'avez que 3 jeux à combiner, faites une boucle et, en cas d'échec, cassez les boucles. (Si votre code est complexe, définir une variable et de briser juste devant

for i1 in [A, B]: 
    for i2 in [C, D]: 
     for i3 in [E, F, G]: 
     if not test(i1, i2, i3): 
      break 

Cependant, si le nombre de jeux que vous avez est variable, utilisez une fonction récursive (backtrack):.

inp_sets = ([A,B],[C,D],[E,F,G]) 
max_col = len(inp_sets) 
def generate(col_index, current_set): 
    if col_index == max_col: 
     if test(current_set): 
      return current_set 
     else: 
      return None 
    else: 
     found = False 
     for item in inp_sets[col_index]: 
      res = generate(col_index+1, current_set + [item]): 
      if res: 
        return res 
      elif (col_index == max_col - 1): 
        # Here we are skipping the rest of the checks for last column 
        # Change the condition if you want to skip for more columns 
        return None 

result = generate(0, []) 
+0

Je pense que vous avez raison - je vais utiliser une approche récursive. Je vais pouvoir consommer beaucoup de sorties, mais l'approche récursive me laisse le contrôle du générateur. – Mike

Questions connexes