I don't know your exact use-case, but if you want to be able to format any type of input users may consider valid, your validation is too strict.
For example these are not valid numbers according to your code:
999-999-9999
+19999999999
+1-999-999-9999
since they contain symbols you're not expecting to find there.
One way to solve it is to simply remove all non-numeric symbols from the string before we process it:
''.join(char for char in phone_number if char.isdigit())
Or if you're a regular expressions enjoyer:
import re
re.sub('[^0-9]', '', phone_number)
This will consider 9999999999abcde a valid number, but do we really care? No one will be deliberately adding those symbols there as phone numbers never include them. If there are any extra symbols that shouldn't be there, we can tolerate them.
But idif you want to deem such numbers as invalid anyway, we can remove only + and - symbols:
phone_number.replace('+', '').replace('-', '')
Or if you're a regular expressions enjoyer:
import re
re.sub('\+|-', '', phone_number)
Nitpicks:
Functions in python are named using snake_case, not CamelCase:
def north_america(...)
Functions' names (and any other names for that matter) should tell us what the purpose of the object is. In this case "north america" doesn't tell us anything - it's only obvious to the author of the code.
def parse_number_as_north_american(...)
Long names are not a problem as long as you can tell what these names actually mean.
final_number = "".join(number_list)
return final_number
can be shortened to
return "".join(number_list)
Creating a new name doesn't help us understand the code, since it's clear that the number we're returning is "final".