HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMajor

Two FizzBuzz solutions

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
twosolutionsfizzbuzz

Problem

Below are two solutions to the FizzBuzz problem in Python. Which one of these is more "Pythonic" and why is it more "Pythonic" than the other?

Solution One:

fizzbuzz = ''

start = int(input("Start Value:"))
end = int(input("End Value:"))

for i in range(start,end+1):
    if i%3 == 0:
        fizzbuzz += "fizz"
    if i%5 == 0:
        fizzbuzz += "buzz"
    if i%3 != 0 and i%5 != 0:
        fizzbuzz += str(i)

    fizzbuzz += ' '

print(fizzbuzz)


Solution Two:

fizzbuzz = []

start = int(input("Start Value:"))
end = int(input("End Value:"))

for i in range(start,end+1):
    entry = ''
    if i%3 == 0:
        entry += "fizz"
    if i%5 == 0:
        entry += "buzz"
    if i%3 != 0 and i%5 != 0:
        entry = i

    fizzbuzz.append(entry)

for i in fizzbuzz:
    print(i)

Solution

As has already been pointed out, creating a list is preferable as it avoids the concatenation of large strings. However neither of your solutions is the most pythonic solution possible:

Whenever you find yourself appending to a list inside a for-loop, it's a good idea to consider whether you could use a list comprehension instead. List comprehensions aren't only more pythonic, they're also usually faster.

In this case the body of the loop is a bit big to fit into a list comprehension, but that's easily fixed by refactoring it into its own function, which is almost always a good idea software design-wise. So your code becomes:

def int_to_fizzbuzz(i):
    entry = ''
    if i%3 == 0:
        entry += "fizz"
    if i%5 == 0:
        entry += "buzz"
    if i%3 != 0 and i%5 != 0:
        entry = i
    return entry

fizzbuzz = [int_to_fizzbuzz(i) for i in range(start, end+1)]


However, while we're at it we could just put the whole fizzbuzz logic into a function as well. The function can take start and end as its argument and return the list. This way the IO-logic, living outside the function, is completely separated from the fizzbuzz logic - also almost always a good idea design-wise.

And once we did that, we can put the IO code into a if __name__ == "__main__": block. This way your code can be run either as a script on the command line, which will execute the IO code, or loaded as a library from another python file without executing the IO code. So if you should ever feel the need to write a GUI or web interface for fizzbuzz, you can just load your fizzbuzz function from the file without changing a thing. Reusability for the win!

def fizzbuzz(start, end):
    def int_to_fizzbuzz(i):
        entry = ''
        if i%3 == 0:
            entry += "fizz"
        if i%5 == 0:
            entry += "buzz"
        if i%3 != 0 and i%5 != 0:
            entry = i
        return entry

    return [int_to_fizzbuzz(i) for i in range(start, end+1)]

if __name__ == "__main__":
    start = int(input("Start Value:"))
    end = int(input("End Value:"))
    for i in fizzbuzz(start, end):
        print(i)


(Note that I've made int_to_fizzbuzz an inner function here, as there's no reason you'd want to call it outside of the fizzbuzz function.)

Code Snippets

def int_to_fizzbuzz(i):
    entry = ''
    if i%3 == 0:
        entry += "fizz"
    if i%5 == 0:
        entry += "buzz"
    if i%3 != 0 and i%5 != 0:
        entry = i
    return entry

fizzbuzz = [int_to_fizzbuzz(i) for i in range(start, end+1)]
def fizzbuzz(start, end):
    def int_to_fizzbuzz(i):
        entry = ''
        if i%3 == 0:
            entry += "fizz"
        if i%5 == 0:
            entry += "buzz"
        if i%3 != 0 and i%5 != 0:
            entry = i
        return entry

    return [int_to_fizzbuzz(i) for i in range(start, end+1)]

if __name__ == "__main__":
    start = int(input("Start Value:"))
    end = int(input("End Value:"))
    for i in fizzbuzz(start, end):
        print(i)

Context

StackExchange Code Review Q#763, answer score: 20

Revisions (0)

No revisions yet.