Where the newline goes
A detail that catches people: print() after the inner loop, indented to the outer loop, ends the row. Indent it one level further and you get a newline after every cell instead. The indentation is the logic here, not decoration.
The cost multiplies
One loop over n items runs n bodies. Two nested loops over n items run n×n. Put them side by side instead of inside each other and you get 2n. The difference between n² and 2n is the difference between a program that scales and one that does not:
- n = 100: nested runs 10,000 bodies, sequential runs 200
- n = 400: nested runs 160,000, sequential runs 800
Doubling the input quadruples nested work. The second program on this page times both at three sizes so the shape is visible rather than asserted.
break only leaves one loop
break exits the loop it is written in. Inside a nested pair, that is the inner loop; the outer one continues with its next pass. If you want out of both, the usual answers are to put the loops in a function and return, or to set a flag the outer loop checks.
If both loops walk the same collection, you are comparing every pair, and that is often avoidable. "Does any pair sum to the target?" looks like a natural nested loop and is a single pass with a set. Nesting is right when the two dimensions are genuinely independent — rows and columns, users and permissions — and suspicious when they are the same thing twice.