Comprehension with two variables - explanation needed

Rustom Mody rustompmody at gmail.com
Sun Nov 23 11:45:39 EST 2014


On Sunday, November 23, 2014 9:27:22 PM UTC+5:30, Roy Smith wrote:
>  Skip Montanaro wrote:
> 
> > > But it breaks all the picture that I've built in my head about comps till
> > > now...
> > 
> > Note that list comprehensions are little more than syntactic sugar for for
> > loops. If you're having terrible writing or understanding one, especially a
> > compound one like your example, it can help to write it as a (nested) for
> > loop, then covert it (perhaps incrementally) to the list comp form.
> 
> Or not.  If it was complicated enough that you needed to loopify it to 
> understand what it's doing, have pity on the next person who has to 
> maintain your code and leave it as a loop :-)
> 
> My general rule for code hygiene is, "If I have to think about whether 
> something is too complicated, it is".

[I guess I am in the minority here... anyways... here goes]

1. I find comprehensions are harder than for-loops -- corollary to
functional code is easier than imperative --
corollary to time is a major headache. If the problem does not
involve time the solution should try to avoid it

2. "List comprehensions are syntactic sugar for for loops"
Cannot technically quarrel with that as that is the position of the official
docs.
However to me it puts the cart before the horse.
Its like saying that 

def foo(x): return x+1

is just the same as

              0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (1)
              6 BINARY_ADD
              7 RETURN_VALUE


(output of dis)

That may be the case but it seems (to me at least) to defeat the purpose
of using an hi-level language.

3. So how should one think of list comprehensions?
   As a python/executable version of 'set-builder notation'
   http://en.wikipedia.org/wiki/Set-builder_notation

4. Finally to the OP (assuming you wanted a prime-number generator)
Heres a solution for your consideration.

First a one-line solution in haskell

sieve (p:xs)   =    p:sieve [x | x <- xs, x `mod` p /= 0]

Call with sieve [2..]

Now a pythonification of that

def n2s():  # natural nos from 2; ie [2..]
    i=2
    while True:
        yield i
        i+=1

def sieve(l):
    p = next(l)
    yield p
    yield from sieve (x for x in l if x % p != 0)


Call as
for p in sieve(n2s()): print(p)



More information about the Python-list mailing list