Reputation: 83187
I want do a Cartesian product between severable iterables in Python and I would like to specify the order of the iteration.
E.g. I have 3 iterables: 'AB', 'xy', '01'
in my example. When I write
import itertools
print list(itertools.product('AB', 'xy', '01'))
the output is in lexicographic order:
('A', 'x', '0')
('A', 'x', '1')
('A', 'y', '0')
('A', 'y', '1')
('B', 'x', '0')
('B', 'x', '1')
('B', 'y', '0')
('B', 'y', '1')
I would like to be able to specify that I want to first iterate on iterable 1 ( 'AB'
), then iterable 3 ( '01'
), then iterable 2 ( 'xy'
), which would give the following output:
('A', 'x', '0')
('B', 'x', '0')
('A', 'x', '1')
('B', 'x', '1')
('A', 'y', '0')
('B', 'y', '0')
('A', 'y', '1')
('B', 'y', '1')
Is there any standard way to do it in Python? I'm OK to use Numpy.
Upvotes: 1
Views: 171
Reputation: 251378
Just pass the iterables in the order you want them to be iterated (or rather, with your terminology, the reverse order --- the first one passed will be the outermost iteration, so it will cycle "slowest"). If you must have the result tuples in a different order, just swap the results afterwards:
>>> [(c, a, b) for a, b, c in itertools.product('xy', '01', 'AB')]
[(u'A', u'x', u'0'),
(u'B', u'x', u'0'),
(u'A', u'x', u'1'),
(u'B', u'x', u'1'),
(u'A', u'y', u'0'),
(u'B', u'y', u'0'),
(u'A', u'y', u'1'),
(u'B', u'y', u'1')]
Note this doesn't require any extra pass over the results: each tuple is swapped as it is generated.
Upvotes: 3