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
?
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.
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
?
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.