Python Default Arguments — What Does This Print?
This is a daily Python challenge from the CodeShot archive. Practice your knowledge of Default Arguments Keyword Arguments and improve your technical interview readiness.
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
print(greet("Alice"))
print(greet("Bob", "Hi"))
print(greet(greeting="Hey", name="Carol"))
Detailed Explanation
Why This Question Matters
On the surface, this looks like a "Hello World" level problem. But if you're interviewing for a senior role or reviewing a junior's PR, this is actually a test of how well you understand Python's argument passing mechanics.
Most developers know that Python supports both positional and keyword arguments. However, the real confusion starts when you mix them. Understanding the priority and the order of operations in function calls is the difference between writing clean, predictable code and spending three hours debugging a TypeError because you passed a value into the wrong parameter.
Understanding the Code
Let's look at the snippet:
Here is what's actually happening under the hood:
The function greet has two parameters. name is a mandatory positional argument, and greeting is a keyword argument with a default value of "Hello".
In the first call, greet("Alice"), Python sees one argument. Since name is the first parameter defined in the function signature, "Alice" is assigned to name. Because we didn't provide a second argument, Python falls back to the default value for greeting.
In the second call, greet("Bob", "Hi"), we provide two positional arguments. Python maps them in order: "Bob" goes to name, and "Hi" overrides the default value for greeting.
The third call, greet(greeting="Hey", name="Carol"), uses keyword arguments. This is where Python gets flexible. Since we explicitly named the parameters, the order no longer matters. Python looks for the keys greeting and name in the function signature and assigns the values accordingly.
Finding the Correct Answer
If you're looking at the options, the correct one is Option B:
Hello, Alice!
Hi, Bob!
Hey, Carol!
Why not the others? Usually, incorrect options suggest that the default value is ignored or that the keyword arguments in the third call are processed in the order they appear in the function definition rather than the order they are passed.
For example, a common mistake is thinking the third line would print Carol, Hey!. That would only happen if we passed them positionally. Because we used greeting="Hey", we told Python exactly which bucket that string belongs in, regardless of where it sits in the call.
Common Mistakes Developers Make
The most common trap here isn't the logic—it's the syntax rules.
The biggest "gotcha" in Python is trying to put a positional argument *after* a keyword argument. If you tried to do this:
greet(greeting="Hey", "Carol")
Python will throw a SyntaxError: positional argument follows keyword argument.
Once you start using keywords in a function call, you've crossed a rubicon; every single argument following that point must also be a keyword argument. This is a frequent source of frustration for devs moving from languages that handle parameter mapping differently.
Another mistake is the "Mutable Default Argument" trap. While not present in this specific snippet (since we used strings), using a list or dictionary as a default value (e.g., def add_item(item, list=[])) is a classic senior-level interview trap. Defaults are evaluated once at definition time, not every time the function is called. If you mutate that list, it stays mutated for every subsequent call.
Real-World Usage
In production, you'll see this pattern everywhere, especially in library design.
Think about a database connection function. You might have a mandatory connection_string, but optional timeout or retry_limit parameters. By using default values, you provide a "sane default" for 90% of users while allowing power users to tweak the behavior without overloading the function with twenty different versions of the same method.
Keyword arguments are also a lifesaver for readability. Compare these two calls:
update_user("jdoe", True, False, True)
update_user("jdoe", verify_email=True, send_welcome=False, notify_admin=True)
The second one is self-documenting. When you're reviewing code six months later, you don't want to have to jump back to the function definition to remember what the third boolean represents.
Key Takeaways
- Positional arguments are mapped by order.
- Keyword arguments are mapped by name, making order irrelevant.
- Defaults only kick in if the argument is omitted from the call.
- The Golden Rule: Never place a positional argument after a keyword argument in a function call.
- Use keywords for any function with more than two or three parameters to keep your code readable and maintainable.
Why this matters
Understanding Default Arguments Keyword Arguments is crucial for passing technical interviews. In real-world applications, this concept often leads to subtle bugs if not handled correctly. For more details, you can always refer to the official MDN Documentation.