Lazy List Generator Problem

Discussion in 'Python' started by Mark Hahnenberg, Jan 16, 2009.

  1. I'm trying to make a lazy, (theoretically) infinite prime number sieve
    using generators. The code I have thus far is:

    #!/usr/bin/env python

    import itertools

    def sieve():
    nats = naturals(2)
    while True:
    elem = nats.next()
    yield elem
    nats = itertools.ifilterfalse(lambda x: x % elem == 0, nats)

    def naturals(start=1):
    curr = start
    while True:
    yield curr
    curr += 1

    primes = sieve()
    i = 0
    while i < 10:
    print primes.next()
    i += 1

    When I execute this code, the numbers 2,3,4,...,11 are printed (i.e.
    nothing gets filtered out). Could anyone explain why this is
    happening? I generally understand generators, and my hypothesis is
    that reassigning to nats the result of filtering nats could be
    screwing things up somehow, but I've tried a variety of other methods,
    from making copies of the old iterator to rolling my own filter
    function and nothing has worked.

    Thanks,
    -MRH
    Mark Hahnenberg, Jan 16, 2009
    #1
    1. Advertising

  2. Mark Hahnenberg

    alex23 Guest

    On Jan 16, 12:42 pm, Mark Hahnenberg <> wrote:
    > When I execute this code, the numbers 2,3,4,...,11 are printed (i.e.
    > nothing gets filtered out).  Could anyone explain why this is
    > happening?  I generally understand generators, and my hypothesis is
    > that reassigning to nats the result of filtering nats could be
    > screwing things up somehow, but I've tried a variety of other methods,
    > from making copies of the old iterator to rolling my own filter
    > function and nothing has worked.


    Hey Mark,

    I think the issue isn't that 'nats' is changing, but that 'elem' is.
    Try replacing this:

    > nats = itertools.ifilterfalse(lambda x: x % elem == 0, nats)


    with this:

    nats = itertools.ifilterfalse(lambda x, elem=elem: x % elem ==
    0, nats)

    Which works for me:

    In [91]: s = sieve()
    In [92]: primes_10 = [s.next() for x in xrange(10)]
    In [93]: primes_10
    Out[93]: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]


    Hope this helps.
    alex23, Jan 16, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Martin Maurer
    Replies:
    3
    Views:
    4,783
    Peter
    Apr 19, 2006
  2. TheDustbustr
    Replies:
    1
    Views:
    437
    Sami Hangaslammi
    Jul 25, 2003
  3. Ken Pu
    Replies:
    3
    Views:
    663
    Steven D'Aprano
    Jan 16, 2009
  4. Boris Borcic
    Replies:
    0
    Views:
    542
    Boris Borcic
    Jan 16, 2009
  5. Boris Borcic
    Replies:
    0
    Views:
    539
    Boris Borcic
    Jan 16, 2009
Loading...

Share This Page