I don't understand why you wouldn't just define a function if you needed multi lines.
For the same reason that you wouldn’t necessarily define a function every time you wanted more than one line in the body of an if statement or for loop.
In a functional programming style, typically most of your control structures are represented as higher-order functions and you pass them other functions where you might use nested blocks of statements in an imperative style.
That is, where imperative pseudocode might look like this:
for n in [0..10]:
output_array[n] = n * n
some corresponding functional pseudocode might look more like this:
output_array = for_each [0..10] (n -> n * n)
In some functional languages, it’s even idiomatic to write the supporting function so it reads more like this (borrowing Haskell’s $ notation, which avoids the awkward parentheses):
output_array = for_each [0..10] $ \n ->
n * n
Now you might want a multiline body for the supporting function in much the same situations that you might want a multiline body for the imperative for loop:
for n in [0..10]:
location = get_location(n)
route = fastest_route_to(location)
times[n] = average_journey_time(route)
times = for_each [0..10] $ \n ->
location = get_location(n)
route = fastest_route_to(location)
average_journey_time(route)
Similarly, if the logic you’re using in the inner part of the code is a self-contained concept, you might want to factor it out into a named function of its own in either case.
This functional style can be tidy and very flexible in languages that are designed to support it. However, I wouldn’t necessarily encourage it in a language like Python, precisely because Python’s syntax and language features don’t make it natural and concise to write like this.