Hamperfait
Hamperfait

Reputation: 515

Python itertools with fix parameters

I am trying to do an iterable but with some fix parameters, and that the iterable parameters are in a list. This is the output of what I'm looking for:

(fix1, fix2, fix3, [iterable1_1, iterable2_1, iterable3_1], fix4)

(fix1, fix2, fix3, [iterable1_1, iterable2_1, iterable3_2], fix4)

etc. Basically, only the three ones inside the list change; the rest don't change.

So far, I've tried this, but it doesn't really work.

iterable = itertools.product([fix1], [fix2], [fix3], [[iter1_1, iter1_2, iter1_3], [iter2_1, iter2_2], [iter3_1, iter3_2, iter3_3]], [fix4])

iter1, iter2 and iter3 have different lengths, but I don't think that's relevant.

An example: I have two lists, a = [1,2] and b = [3,4] and some fix parameters f1 = 10, f2=20, f3=30 The desired output would be:

(10, 20, [1,3], 30)
(10, 20, [1,4], 30)
(10, 20, [2,3], 30)
(10, 20, [2,4], 30)

Upvotes: 0

Views: 667

Answers (3)

wwii
wwii

Reputation: 23753

import itertools
a = [1,2]
b = [3,4]
f1 = 10
f2 = 20
f3 = 30

Get the product of a and b

things = itertools.product(a,b)

Construct the result using the fixed values and the products

z = [(f1, f2, thing, f3) for thing in map(list, things)]


>>> for thing in z:
    print thing

(10, 20, [1, 3], 30)
(10, 20, [1, 4], 30)
(10, 20, [2, 3], 30)
(10, 20, [2, 4], 30)
>>>

It's not generic, it will not handle an arbitrary number of fixed things and iterable things.

Here is a more generic solution

def f(fixed, iterables):
    things = itertools.product(*iterables)
    last = fixed[-1]
    for thing in things:
        out = fixed[:-1]
        out.extend((thing, last))
        yield out

Usage:

for thing in f([f1, f2, f3, f4], [a, b]):
    print thing

Upvotes: 2

Blckknght
Blckknght

Reputation: 104722

It sounds like you want something like:

result = [(fix1, fix2, fix3, [a, b, c], fix4)
          for a, b, c in itertools.product(iterable1, iterable2, iterable3)]

If the inner sequence with a, b, c can be a tuple rather than a list, you would not need the unpacking:

result = [(fix1, fix2, fix3, prod, fix4) for prod in product(...)]

Upvotes: 2

9000
9000

Reputation: 40894

If in doubt, create a function.

def framed(*iters):
    for pair in itertools.product(*iters):
        yield (10, 20, pair, 30)

for result in framed([1, 2], [3, 4]):
    print result

(10, 20, (1, 3), 30)
(10, 20, (1, 4), 30)
(10, 20, (2, 3), 30)
(10, 20, (2, 4), 30)

Upvotes: 1

Related Questions