We want to pause for a moment before saying 'yes' to this being a generalization.
In truth, for this instance at least and most common, the return statement is in the same block as the for statement. The block defined by the function header. In Python, a block starts with a colon, immediately following the header line.
Think of an if statement and a for statement as objects, and like all objects, they have self context. The segment of code in their block is in that context, so iterator variables have a sort of scope. Not function scope, so much, just a more localized scope that stays within the context.
It is these localized contexts that indentation signifies to the interpreter.
A general term that is common in referring to the environment is namespace and it refers to the reserved space in which the interpreter, all modules and classes, functions and variables reside. To keep conflicts from arising, functions are given their own scope; that is, their own environment that can look out, but can't be seen from outside.
while, etc. have a localized form of that environment where transient variables such as the iterator in
for are unseen, even in their parent scope unless we let them be seen. Again, it is indentation that let's us demarcate these localized scopes (not really scope, but analogous).
The reason they are localized is because they do not have a return method in their attributes. They are in direct contact with all variables within local and global scope. A function object does have a
return method so it can be closed off. Looping and control flow constructs have to be out in the open as it were, but they are still contained in their parent scope.
As for indentation, as Python is concerned it matters not what form the indent takes, spaces (any number) or tabs (likewise). But we should not mix spaces and tabs because that messes with the interpreter. In recent news I read that people who use spaces as a rule earn 20_000 dollars or more a year than those who use tabs. Not my study so I am not going to defend that finding. It is interesting, though.
Generally speaking, even numbers only makes it easier to standardize and adopt typing habits. The norm may be four spaces, but two is just as valid, and equally representative of blocks. (Remember, Python doesn't care, just so it is consistent and accurate.)
In simple terms, if it starts with a colon, the next and succeeding lines have an indent of two or four spaces (choose, and then stick with it) as compared with the header line. The block ends when a line of code is found that matches the indentation of the header. That is why it is so important to indent return statements, else it raises an exception.
An exception is a run time error. A syntax error happens in parsing the code by the interpreter. A program may run with errors, but they cannot be syntax errors. That stops the pasing process so no code ever executes.