Reputation: 4622
Consider this code, wherein I use combinations
and attempt to make a list out of them.
from itertools import combinations
t = (1,2,3,4)
print("t is %r" % (t,))
print("list(t) is %r" % list(t))
print("list(t) is %r" % list(t))
t2 = ("a", "b", "c", "d")
print("t2 is %r" % (t2,))
combs = combinations(t2, 2)
print("List of combinations of t2: %r" % list(combs))
print("List of combinations of t2: %r" % list(combs))
The output is (unexpectedly for me)
t is (1, 2, 3, 4)
list(t) is [1, 2, 3, 4]
list(t) is [1, 2, 3, 4]
t2 is ('a', 'b', 'c', 'd')
List of combinations of t2: [('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')]
List of combinations of t2: []
So clearly, list()
has side-effects.
As expected, converting a tuple to a list does not change the original data, I can do it multiple times. But when I try the same with an iterable returned from combinations
, this works only once and then the iterable is seemingly invalid. Does list
call next
on the iterable so that after it is done, the iterator is at the end or why does this happen?
And how can I avoid it?
Upvotes: 1
Views: 63
Reputation: 86502
As you have correctly observed, list
is destructive, as a generator can only be exhausted once. A simple solution is to use itertools.tee
:
>>> c1, c2 = itertools.tee(itertools.combinations(["a", "b", "c"], 2))
>>> print(list(c1))
... will print the entire sequence of combinations
>>> print(list(c2))
... same as before
This may be more memory-conservative as holding on to the entire list, as itertools.tee
only needs to hold on to the elements that have not been consumed by all iterators.
Upvotes: 0
Reputation: 49318
itertools.combinations
produces a lazy generator, not a complete data structure that gets saved in memory. Once you exhaust it (iterate through it) with something like list()
, it is... well, exhausted. Empty. If you want to use it repeatedly, save a reference:
combs = list(combinations(t2, 2))
print("List of combinations of t2: %r" % combs)
print("List of combinations of t2: %r" % combs)
Upvotes: 3