Reputation: 969
I have been looking at collections.Counter.
I am using the following (simplified) code:
choices = ['foo', 'bar']
def generator(n=100000000):
yield random.choice(choices)
counts = collections.Counter(generator())
Now my question, in my implementation Counter
takes a generator as input. To first convert the generator to a list would take way too much space in memory.
So I wonder if collections.Counter
first converts the data to a list and then 'counts' or it 'eats' the generator while counting.
If it first converts the data to a list. How would I best go about implementing it without converting it to a list.
Upvotes: 0
Views: 563
Reputation: 1122152
No, the iterable you pass in (be it a generator or another iterable object) is not converted to a list.
There is no need to convert the iterable; counting is done as you iterate. The implementation is essentially the same as:
counts = {}
for element in generator():
if element in counts:
counts[element] += 1
else:
counts[element] = 1
but a Counter()
object does this much faster (the counting code is implemented in C).
Upvotes: 3