I've always been pretty weak at algorithms, so I'm trying to improve. Specific feedback on performance would be appreciated.
The thing is FizzBuzz is not a problem that shows your algorithms knowledge, I've seen lots of solutions and never seen one done in O(n^2). I mean if you will think about it, you might find a solution in O(n^2) but most obvious solutions will still be O(n). So again this problem is not about algorithms.
The main goal of FizzBuzz is just to show your basic knowledge on specific programming language since it contains all the main operations (loop, output and number operations). It's also a good thing to have a basic image on candidate coding style.
If I would be asked to solve a fizzbuzz I will do something like this:
def real_fizz_buzz(fizz=3, buzz=5):
print(*('Fizz'*(not i % fizz)+'Buzz'*(not i % buzz) or i for i in range(1, 101)), sep='\n')
Or this:
print(*(map(lambda x: 'Fizz'*(not x % fizz)+'Buzz'*(not x % buzz) or x, range(1, 101))), end='\n')
Or using F literal:
print(*map(lambda x: f"{'Fizz' * (not x%3)}{'Buzz' * (not x%5)}" or x, range(1,101)), sep='\n')
I know this is something that is not easy to read for a beginner, but I just like that python allows you to solve that simple problem in one line and I would use it if I would be asked.
However, my personal opinion that is long as a candidate can solve this problem and does it in O(n), it's fine and acceptable.
So for this particular problem just use any solution that is easier for you to write and understand.