Erel Segal-Halevi
Erel Segal-Halevi

Reputation: 36745

Can I create a generator that returns its length?

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

Answers (3)

00sdf0
00sdf0

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

Duncan
Duncan

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

pd shah
pd shah

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

Related Questions