itertools combination can only work for one copy

Question:

when I use combinations from itertools, I find that I can only use it once, and afterwards I must repeat the line of code for it to work again. For example,

from itertools import combinations
comb = combinations( range( 0 , 5 ) , 2 )
xyLabels = [ (f'PCA{x}', f'PCA{y}') for x , y in  comb ]

>[('PCA0', 'PCA1'), ('PCA0', 'PCA2'), ('PCA0', 'PCA3'), ('PCA0', 'PCA4'), ('PCA1', 'PCA2'), ('PCA1', 'PCA3'), ('PCA1', 'PCA4'), ('PCA2', 'PCA3'), ('PCA2', 'PCA4'), ('PCA3', 'PCA4')]

Whereas If I do the following:

comb = combinations( range( 0 , 5 ) , 2 )
xyLabels = [ (f'PCA{x}', f'PCA{y}') for x , y in  comb ]
yxLabels = [ (f'PCA{x}', f'PCA{y}') for x , y in  comb ]
print(yxLabels)
> []

Printing the secod argument will only produce an empty list. However, to solve this I have to do the following:

comb = combinations( range( 0 , 5 ) , 2 )
xyLabels = [ (f'PCA{x}', f'PCA{y}') for x , y in  comb ]
comb = combinations( range( 0 , 5 ) , 2 )
yxLabels = [ (f'PCA{x}', f'PCA{y}') for x , y in  comb ]
print(yxLabels)

What is the reason behind it and how can I get it to work with only one comb?

Asked By: tesla john

||

Answers:

You need to define comb as a list instead of a generator – like this:

comb = list(combinations( range( 0 , 5 ) , 2 ))

That will then give you the result you expect. it will however increase your memory utilisation because you evaluate comb fully, instead of having it wait in the wings to hand you values on demand. Whether the memory/convenience tradeoff is worth it is your call.

Answered By: Vin
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.