Get the cartesian product of a series of lists?
itertools.product
Available from Python 2.6.
import itertools
somelists = [
[1, 2, 3],
['a', 'b'],
[4, 5]
]
for element in itertools.product(*somelists):
print(element)
Which is the same as,
for element in itertools.product([1, 2, 3], ['a', 'b'], [4, 5]):
print(element)
Cartesian product of two lists in python
Do a list comprehension, iterate over both the lists and add the strings, like
list3 = [i+str(j) for i in list1 for j in list2]
How to get a Cartesian product of a list containing lists?
Here is a LINQ extension method using Aggregate
:
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) =>
sequences.Aggregate(
Enumerable.Empty<T>().AsSingleton(),
(accumulator, sequence) => accumulator.SelectMany(
accseq => sequence,
(accseq, item) => accseq.Append(item)));
You need the extension method AsSingleton
:
public static IEnumerable<T> AsSingleton<T>(this T item) => new[] { item };
This is based on this answer from @EricLippert.
Getting the cartesian product of two lists as a list-of-lists
well, you just needed one more level of list.
deck = [[x+y for x in value] for y in deck_types]
n-fold Cartesian product on a single list in Python
itertools.product
takes a keyword argument to indicate the given arguments should be repeated.
>>> from itertools import product
>>> list(product([1,2], repeat=0))
[()]
>>> list(product([1,2], repeat=1))
[(1,), (2,)]
>>> list(product([1,2], repeat=2))
[(1, 1), (1, 2), (2, 1), (2, 2)]
This works with multiple iterables as well.
# Equivalent to list(product([1,2], ['a', 'b'], [1,2], ['a', 'b']))
>>> list(product([1,2], ['a', 'b'], repeat=2))
[(1, 'a', 1, 'a'), (1, 'a', 1, 'b'), (1, 'a', 2, 'a'), (1, 'a', 2, 'b'), (1, 'b', 1, 'a'), (1, 'b', 1, 'b'), (1, 'b', 2, 'a'), (1, 'b', 2, 'b'), (2, 'a', 1, 'a'), (2, 'a', 1, 'b'), (2, 'a', 2, 'a'), (2, 'a', 2, 'b'), (2, 'b', 1, 'a'), (2, 'b', 1, 'b'), (2, 'b', 2, 'a'), (2, 'b', 2, 'b')]
Improving the performance of cartesian product of multiple lists
A few comments:
If you think about it, what
car_multiple_sets
is doing is iterating on its parameterlists
. You're doing that using recursion, but iterating on a list can also be done with afor
-loop. And it so happens that recursion is somewhat slow and memory-inefficient in python, sofor
-loops are preferable.You don't need to convert to
str
to group the ints together. You can usetuples
. That's precisely what they're for. Replacestr(x)+str(y)
with(x,y)
to get a pair of two integers instead of a string.
def car_two_sets(a, b, unpack=False):
if unpack:
return [(*x, y) for x in a for y in b]
else:
return [(x, y) for x in a for y in b]
def car_multiple_sets(lists):
if len(lists) == 0:
return [()] # empty Cartesian product has one element, the empty tuple
elif len(lists) == 1:
return list(zip(lists[0])) # list of "1-uples" for homogeneity
else:
result = car_two_sets(lists[0], lists[1])
for l in lists[2:]:
result = car_two_sets(result, l, unpack=True)
return result
print( car_multiple_sets((range(3), 'abc', range(2))) )
# [(0, 'a', 0), (0, 'a', 1), (0, 'b', 0), (0, 'b', 1), (0, 'c', 0), (0, 'c', 1),
# (1, 'a', 0), (1, 'a', 1), (1, 'b', 0), (1, 'b', 1), (1, 'c', 0), (1, 'c', 1),
# (2, 'a', 0), (2, 'a', 1), (2, 'b', 0), (2, 'b', 1), (2, 'c', 0), (2, 'c', 1)]
Related Topics
Beautiful Soup Findall Doesn't Find Them All
Python: How to Kill Child Process(Es) When Parent Dies
Python Multiprocessing: Permission Denied
Converting Epoch Time With Milliseconds to Datetime
How to Iterate Over Rows in a Dataframe in Pandas
What Do Lambda Function Closures Capture
How Is Returning the Output of a Function Different from Printing It
Why Does "Pip Install" Inside Python Raise a Syntaxerror
Does Pandas Iterrows Have Performance Issues
Logical Operators For Boolean Indexing in Pandas
How to Remove Script Tags With Beautifulsoup
Python - Is Time.Sleep(N) Cpu Intensive
Integer Division by Negative Number
How to Convert String Representation of List to a List
How to Import a Module Given the Full Path