有限制的itertools.product

时间:2019-06-07 23:45:35

标签: python itertools

给出以下变量列表:

greek = ['alpha', 'beta', 'gamma']
numbers = [1, 2, 3]
latin = ['x', 'y']

我的基准选择是['alpha', 1, 'x']。我想生成以下变体,一次更改一个参数:

variations = [
        ['beta', 1, 'x'], ['gamma', 1, 'x'],  # Varying greek
        ['alpha', 2, 'x'], ['alpha', 3, 'x'], # Varying numbers
        ['alpha', 1, 'y'],                    # Varying latin
        ]

我可以使用it.product()生成所有组合的完整矩阵,并且我也可以通过几行代码获得所需的结果。

什么是实现该目标的好方法?将其推广到许多参数集将是很棒的。

2 个答案:

答案 0 :(得分:2)

一种可能的非itertools解决方案是使用具有递归的生成器:

def product(args, c = []):
   if not args:
      yield c
   else:
      for i in args[0]:
         yield from product(args[1:], c+[i])

greek = ['alpha', 'beta', 'gamma']
numbers = [1, 2, 3]
latin = ['x', 'y']
r, seen = list(product([greek, numbers, latin])), []
for i in r:
  if all(len(set(i) & set(k)) == 1 or i[0] != k[0] for k in seen):
    seen.append(i)

print(seen)

输出:

[['alpha', 1, 'x'], ['alpha', 2, 'y'], ['beta', 1, 'x'], ['beta', 2, 'y'], ['gamma', 1, 'x'], ['gamma', 2, 'y']]

答案 1 :(得分:1)

因此,对于数组中的每个位置,您只能迭代一个位置:

greek = ['alpha', 'beta', 'gamma']
numbers = [1, 2, 3]
latin = ['x', 'y']

arrays = [greek, numbers, latin]

default = [arr[0] for arr in arrays]

for x, iter_arr in enumerate(arrays):
    #arr = [arr[0] for arr in arrays]
    iter_arr = arrays[x]
    for item in iter_arr[1:]:
        default[x] = item
        print(default)
    default[x] = arrays[x][0]

我可以问一下它的用途是什么,或者这个迭代有名字吗?