0

Say I have the following list:

raw_list = ['a', ['x', 'xx'], 'b', 'c', ['y', 'yy', 'yyy'], 'd']

And I would like to distribute the nested lists inside it so that from them only one element each appears in the combinations while maintaining order:

[['a', 'x', 'b', 'c', 'y', 'd'],
 ['a', 'x', 'b', 'c', 'yy', 'd'],
 ['a', 'x', 'b', 'c', 'yyy', 'd'],
 ['a', 'xx', 'b', 'c', 'y', 'd'],
 ['a', 'xx', 'b', 'c', 'yy', 'd'],
 ['a', 'xx', 'b', 'c', 'yyy', 'd']]

I wrote the following code to do that:

from pprint import pprint
from itertools import tee

nested = [(e, raw_list .index(e)) for e in raw_list if len(e) > 1] 

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

combinations = []
raw_copy = raw_list[:]
for current, next_ in pairwise(nested):
    for x in current[0]:
        for y in next_[0]:
            raw_copy[current[1]] = x
            raw_copy[next_[1]] = y
            combinations.append(raw_copy)
            raw_copy = raw_list[:]

pprint (combinations)

It does the job. But I am wondering if there is a more Pythonic function or way to achieve the same?

1 Answers1

2

You can use itertools.product:

from itertools import product
raw_list = ['a', ['x', 'xx'], 'b', 'c', ['y', 'yy', 'yyy'], 'd']
result = list(map(list, product(*[[i] if not isinstance(i, list) else i for i in raw_list])))

Output:

[['a', 'x', 'b', 'c', 'y', 'd'], 
 ['a', 'x', 'b', 'c', 'yy', 'd'], 
 ['a', 'x', 'b', 'c', 'yyy', 'd'], 
 ['a', 'xx', 'b', 'c', 'y', 'd'], 
 ['a', 'xx', 'b', 'c', 'yy', 'd'], 
 ['a', 'xx', 'b', 'c', 'yyy', 'd']]
Ajax1234
  • 69,937
  • 8
  • 61
  • 102