Search code examples
pythonfizzbuzz

FizzBuzz list comprehension


I was messing around with some different fizz buzz scripts as I learn python. I came across this one which works great but I can't decipher how it works. I know how the normal fizz buzz works with a for loop and "if i % 3 == 0 and i % 5 == 0". What has me stumped is how "Fizz"(not i%3) + "Buzz"(not i%5)" works.

x = ["Fizz"*(not i%3) + "Buzz"*(not i%5) or i for i in range(1, 100)]

Solution

  • In python you can replicate a string by using the multiplication operator:

    print('aaa' * 3) # aaaaaaaaa
    

    Also, boolean values are implicitly casted to integers on multiplication. Thus, if you do

    "Fizz"*(not i%3)
    

    First, the i%3 will return the result of the modulo. Then, the not operator will convert it to either True if the result was 0, or to False otherwise (by casting it to boolean and then negating the value). By then applying a multiplication operator, False turns to 0 and True turns into 1.

    Thus, if the number is divisible by 3, we get 0 as the result of the modulo, True when applying not, 1 when multiplying, and the string Fizz replicated 1 time as the result of the multiplication. If it is not divisible, we get 0 as operand for the multiplication, effectively getting the string Fizz replicated 0 times, thus an empty string.

    The same goes for Buzz, and the result for each i in the range is just the concatenation of the two.