advanced listcomprehenions?

Mark Wooding mdw at distorted.org.uk
Thu Jun 19 13:57:47 CEST 2008


Gabriel Genellina <gagsl-py2 at yahoo.com.ar> wrote:

> [(not x%3 and not x%5 and "FizzBuzz") or (not x%3 and "Fizz") or (not x%5  
> and "Buzz") or x for x in xrange(1,101)]

Rather unpleasant.  Note that a number is zero mod both 3 and 5 if and
only if it's zero mod 15.  But we can do better.  

A simple application of Fermat's Little Theorem (to distinguish units
mod 3 and 5 from non-units) gives us this:

  [['FizzBuzz', 'Buzz', 'Fizz', False][pow(i, 2, 3) + 2*pow(i, 4, 5)] or
   str(i) for i in xrange(1, 101)]

This is still inelegant, though.  We can glue the results mod 3 and 5
together using the Chinese Remainder Theorem and working mod 15
instead.  For example,

  [['Fizz', 'FizzBuzz', False, None, 'Buzz'][(pow(i, 4, 15) + 1)%7] or
   str(i) for i in xrange(1, 101)]

(A less mathematical approach would just use i%15 to index a table.  But
that's not interesting. ;-) )

-- [mdw]



More information about the Python-list mailing list