Python itertools 跳过元素

5

我有一个嵌套列表的列表。使用itertools,我基本上在做以下操作:

for result in product([A,B],[C,D],[E,F,G]): # 测试每个结果

结果是所需的乘积,每个结果都包含来自列表中的一个元素。我的代码逐个测试每个结果的元素,寻找第一个(也是最好的)“好”的结果。可能需要测试非常多的结果。

假设我正在测试第一个结果“ACE”。假设当我测试第二个元素“C”时,发现“ACE”是一个坏结果。没有必要测试“ACF”或“ACG”。我希望从失败的“ACE”直接跳到尝试“ADE”。有没有办法做到这一点而不仅仅是将不需要的结果丢弃?

如果我使用嵌套的for循环来实现这个功能,我将尝试在循环内部操纵for循环索引,这样做不太好...但我确实想跳过测试许多结果。我能否高效地在itertools中跳过前面的结果?


2
如果“C”是一个坏结果,那么当你到达“BCE”时它是否仍然是一个坏结果?一个单独的元素总是不好的吗,还是只有在特定的组合中才不好? - snapshoe
@Rod。那是有史以来最好的重新标记之一。 - aaronasterling
单独的元素并不是坏的,只有元素之间的组合才会变得糟糕。 - Mike
1个回答

1

使用itertools并不是解决您所面临问题的最佳方式。

如果您只需要合并3个集合,只需循环遍历,当失败时中断循环即可。(如果您的代码比较复杂,请设置一个变量并在外部立即中断。)

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

然而,如果您拥有的集合数量是可变的,则使用递归函数(回溯):

 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, [])

我认为你是对的 - 我将使用递归方法。itertools 可以让我消耗大量输出,但递归方法让我掌控生成器。 - Mike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接