You are going to print the string "Buzz"
either once if (i % 5 == 0)
is True or return i
:
In [5]: "foo" * 2
Out[5]: 'foofoo'
In [6]: "foo" * 3
Out[6]: 'foofoofoo'
In [7]: i = 5
In [8]: "foo" * (i % 5 == 0) or i
Out[9]: 'foo'
In [9]: "foo" * (i % 5 == 1) or i
Out[22]: 5
The same logic applies to "Fizz" sometimes (i % 3 == 0)
will be True so we see it once, when it is False we don't see it.
When you use the *
operator on a string it will repeat the string n
times, in this case it will once at most as either string is only printed based on the result of the boolean test.
You can see in ipython exactly what happens with True
and False
:
In [26]: "foo" * True
Out[26]: 'foo'
In [27]: "foo" * False
Out[27]: ''
Basically True * "foo"
is equivalent to 1 * "foo"
"foo" * False
is equivalent to 0 * "foo"
Bool is a subclass of int so the code is taking advantage of that fact, you sometimes see similar logic used with indexing a list based on a test although not recommended:
In [31]: d = ["bar","foo"]
In [32]: d[3<2] # False so we get 0 the first element
Out[32]: 'bar'
In [33]: d[3>2] # True so we get 1 the second element
Out[33]: 'foo'