AI Hints
Home›Python Tutorial›Functions and Comprehensions
Python · Lesson 11 of 49

Advanced Functions

Args, kwargs, lambda and recursion.

⏱ 2 min read▶ Video at 35:29🎓 Free
Watch this lesson in the Python courseWatch on YouTube ↗Full Python course

Ava's friends loved the add tax function, and now they want more. A function that adds any number of prices. A function that accepts optional settings. A tiny function to sort plants by price, without a full definition. Python has tools for each of these, and we will meet them one by one.

Advanced Functions
From the video: Advanced Functions
  • Any number of arguments
  • Optional named settings
  • Tiny throwaway functions

*args: any number of values

Put a star before a parameter name, and it collects all the extra positional arguments into a tuple. By convention it is called args. Now the same function adds two prices, or twenty. You can also do the reverse, and spread a list into arguments, by placing a star before it in the call.

args.pypython
def add_all(*args):
    print(args)
    return sum(args)

print(add_all(5, 10))
print(add_all(5, 10, 20, 40))
prices = [3, 4, 5]
print(add_all(*prices))
Output
(5, 10)
15
(5, 10, 20, 40)
75
(3, 4, 5)
12

**kwargs: named options

Two stars collect extra named arguments into a dictionary, conventionally called kwargs. This is how flexible tools accept many optional settings. And you can spread a dictionary into named arguments, by placing two stars before it, in the call.

kwargs.pypython
def order(item, **kwargs):
    print(item, kwargs)

order("fern")
order("rose", color="red", gift=True)
opts = {"size": "large", "gift": False}
order("ivy", **opts)
Output
fern {}
rose {'color': 'red', 'gift': True}
ivy {'size': 'large', 'gift': False}

Lambda: tiny functions

A lambda is a small unnamed function, written on one line. The word lambda, then parameters, a colon, and the result. They shine as short helpers. Here, Ava sorts plants by price, by passing a lambda as the key. The key function tells sort what to compare.

lambda.pypython
plants = [("fern", 9.5), ("rose", 11.0), ("ivy", 7.0)]
square = lambda x: x * x
print(square(6))
plants.sort(key=lambda p: p[1])
print(plants)
cheap = sorted(plants, key=lambda p: p[1])[0]
print(cheap)
Output
36
[('ivy', 7.0), ('fern', 9.5), ('rose', 11.0)]
('ivy', 7.0)

Functions are values

In Python, functions are objects, just like numbers. You can store them in variables, put them in lists, and pass them to other functions. Here, a function takes another function and applies it to every price. Map and filter are built in versions of this idea.

first_class.pypython
def apply(fn, items):
    return [fn(i) for i in items]

def cheaper(p):
    return p - 1

print(apply(cheaper, [10, 20]))
print(list(map(lambda x: x * 2, [1, 2, 3])))
print(list(filter(lambda x: x > 1, [1, 2, 3])))
Output
[9, 19]
[2, 4, 6]
[2, 3]

Recursion: a function that calls itself

Recursion means a function calls itself, on a smaller problem. It needs a base case, where it stops, and a recursive case, where it calls itself. Here, we count down from three. And factorial multiplies a number by the factorial of the one below. Recursion suits trees and nested data, while loops suit simple repetition.

recursion.pypython
def countdown(n):
    if n == 0:
        print("Go!")
        return
    print(n)
    countdown(n - 1)

def fact(n):
    return 1 if n <= 1 else n * fact(n - 1)

countdown(3)
print(fact(5))
Output
3
2
1
Go!
120

A flexible total

Your turn. Write a function that accepts any number of prices, and an optional discount named percent, which defaults to zero. It returns the total after the discount. Ready? Here is one solution. Star args for the prices, a default for the percent, and a little maths.

✍️ Exercise: A flexible total

Write total(*prices, percent=0) that returns the sum minus the percentage discount.

Show hint

*prices collects the values

Show solution
flex_total.pypython
def total(*prices, percent=0):
    s = sum(prices)
    return s - s * percent / 100

print(total(10, 20, 30))
print(total(10, 20, 30, percent=10))
Output
60.0
54.0

Summary

Great progress. You can now accept any number of arguments with star args, collect named options with kwargs, write tiny lambdas, treat functions as values, and solve problems with recursion. Next, you will learn the most Pythonic trick of all, comprehensions.

Key takeaways
  • *args and **kwargs for flexibility
  • lambda for small throwaway functions
  • Recursion needs a base case
Next up: Comprehensions — build lists in a single line