Reputation: 36745
Suppose I create this generator:
def first10():
for i in range(10):
yield i
I want to enable the users of this generator to say "len(first10())" and get "10".
I tried this:
first10.__len__ = lambda self: 10
but it did not work - I got an error "object of type 'function' has no len()". Is there another solution?
Upvotes: 0
Views: 82
Reputation: 148
Perhaps something like this?
from itertools import tee
a = (x for x in range(10))
a, b = tee(a,2)
print(sum([1 for x in b]))
>>> 10
tee
creates n
identical iterables, if you create two you can use one to get the length (in any desirable exhaustive or non-exhaustive method) of the other.
Edit:
print(len(list(a))
Coverts your generator to a list, but now you can check the length using len().
Upvotes: 1
Reputation: 95652
Use a class:
class FirstN():
def __init__(self, n=10):
self.n = n
def __len__(self):
return self.n
def __iter__(self):
for i in range(self.n):
yield i
first10 = FirstN(10)
>>> first10 = FirstN(10)
>>> len(first10)
10
>>> for i in first10:
print(i)
0
1
2
3
4
5
6
7
8
9
>>>
Note that with this implementation you don't have to call first10
to iterate over it. If you want to have to call it then use FirstN()
directly and you can call len(FirstN())
and iterate over FirstN()
.
Upvotes: 2
Reputation: 1406
check this
>>> def first10():
for i in range(10):
yield i
>>> len([i for i in first10()])
10
>>> ([i for i in first10()]).__len__()
10
Upvotes: 0