# How to make "zip" work faster?

I have these two finite sets $A$ and $B$ where the size of $A$ is typically much larger than the size of $B$. (typically $|A| is 200-500$ and $|B| is 10-50$) I am trying to enumerate all possible maps from $B$ to $A$ using the following idea - but this turns out to be very slow.

• Is there a way to speed this up?

• Without the over all "for i" loop can I access any one of the "k"s? (for every i each $l$ is a list of tuples)

How can I just pick out any one such "k" list without wanting to wait for the whole code to run.

S = []
from itertools import product

for i in product(A,repeat = len (B)):

k = zip(B,i)
S.append(k)

show(S)


edit retag close merge delete

The number of such maps will be |A|**|B|. You're trying to store all 200**10 (lower bound) such elements in a single list? That's not practical: you should try to construct an iterator instead of a list.

Sort by » oldest newest most voted

As @John Palmieri suggests, use iterators instead of lists.

You are already importing product from the itertools module, learn more about it, especially izip to replace zip.

Here is how to use iterators instead of lists.

from itertools import product
from itertools import izip

A = range(3)
B = range(2)

S = (izip(B,i) for i in product(A, repeat=len(B)))


To compare this code with the code quoted in the question,

• S is now an iterator instead of a list. This is achieved by doing S = (... for ... in ...).
• each elementof S is now an iterator instead of a list. This is achieved by using izip instead of zip.

A good resource for learning about iterators is the SageMath thematic tutorial on comprehensions, iterators ind iterables.

more

I need to analyze each mapping one by one. So does "k = zip(B,i)" be exactly replaced by "k = izip(B,i)" ?

Maybe you don't want each element of S to be an iterator. In that case, keep using zip instead of izip. But certainly you want S itself to be an iterator. The good solution for you might be:

S = (zip(B,i) for i in product(A, repeat=len(B)))