Python itertools 跳过元素

5 投票
1 回答
1049 浏览
提问于 2025-04-16 07:08

我有一个包含多个列表的列表。通过使用itertools库,我基本上是在做这样的事情:

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

这样得到的结果就是我想要的组合,每个结果都包含了来自每个列表的一个元素。我的代码会逐个测试这些结果,寻找第一个(也是最好的)“好”结果。但是要测试的结果可能会非常非常多。

假设我在测试第一个结果'ACE'。如果在测试第二个元素'C'时,我发现'ACE'是个坏结果,那我就不需要再测试'ACF'或'ACG'了。我想直接跳到尝试'ADE'。有没有办法做到这一点,而不是把那些不想要的结果直接丢掉呢?

如果我用嵌套的for循环来实现这个,我会在循环内部试图调整循环的索引,这样做会很麻烦……但我确实想跳过很多结果。请问在itertools中,有没有高效的方法可以跳过一些测试呢?

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

撰写回答