Python Tricks

Let's close out the semester with some fun Python shorthand and tricks. These are conveniences that are available to the experienced programmer, and they help you program faster when appropriately used.

Default Function Arguments

Functions have arguments, as you know, but did you know you can define them so that their arguments have default values? This allows the caller of your function to not include all the arguments if they don't want to.

Here's a basic function we're used to seeing:

def get_positives(N):
    """ 
    Get a list of positive ints from the user.
    Keep asking if they enter negative ints.
    """
    nums = []
    for i in range(N):
        num = -1
        while num < 0:
            num = int(input('Enter an int: '))
        nums.append(num)
    return nums

if __name__ == '__main__':
    nums = get_positives(5)
    print(nums)

This requires the caller to give a number N of how many ints they want. But we could write this so the caller doesn't have to do that!

def get_positives(N=10):
    """ 
    Get a list of positive ints from the user.
    Keep asking if they enter negative ints.
    """
    nums = []
    for i in range(N):
        num = -1
        while num < 0:
            num = int(input('Enter an int: '))
        nums.append(num)
    return nums

if __name__ == '__main__':
    nums = get_positives()
    print(nums)

Look at where we call get_positives() now with no arguments. Neat! This gives the caller some flexibility by defining default values when they leave it unspecified. They can still do get_positives(5) if they just want a list of 5.

def get_positives(N=10, prompt='Enter an int: '):
    """ 
    Get a list of positive ints from the user.
    Keep asking if they enter negative ints.
    """
    nums = []
    for i in range(N):
        num = -1
        while num < 0:
            num = int(input(prompt))
        nums.append(num)
    return nums

if __name__ == '__main__':
    nums = get_positives()   # gets 10
    nums = get_positives(4)  # gets 4
    nums = get_positives(4, 'Give me an int: ')      # gets 4 with a custom prompt
    nums = get_positives(prompt='Give me an int: ')  # gets 10 of them!
    print(nums)

The bottom here shows 4 different ways of calling it. The last one is most interesting. If you have default values in a function, then the caller can specify the exact argument they want to give a value, while skipping others before it.

You can dive deeper into this by reading more about it here.

Sorting with Functions

Sorting is an important algorithm you'll use over and over again. The sorted() function has been our tool for the most part, doing what you'd expect:

>>> nums = [4, 6, 7, -3, 4, 1, -8, 9, 3, -2, 0]
>>> sorted(nums)
[-8, -3, -2, 0, 1, 3, 4, 4, 6, 7, 9]

However, what if we want to sort these numbers based on their absolute values? We're a little stuck here. We need some way of telling Python not to sort them by their numeric comparison (a < b) but rather their comparison after converting each element (abs(a) < abs(b)). Python lets you apply any arbitrary function to each element before it does its comparison. You just give the function an optional argument:

>>> nums = [4, 6, 7, -3, 4, 1, -8, 9, 3, -2, 0]
>>> sorted(nums)
[-8, -3, -2, 0, 1, 3, 4, 4, 6, 7, 9]
>>> sorted(nums, key=abs)
[0, 1, -2, -3, 3, 4, 4, 6, 7, -8, 9]

Look what we did! We combined our first trick with the second. The key argument is a named argument that expects a function as its value. If you don't give one, its default is to use the < comparator.

You can do the same with strings. Let's sort words by their lowercased values even though the words aren't lowercased in the list. To do this, we need to write a lowercase function that takes a string and returns the lowercased version:

>>> words = [ 'hi', 'Bye', 'Happy', 'hello', 'OK', 'Apple', 'zoo' ]
>>> def mylower(s): return s.lower()
>>> sorted(words)
['Apple', 'Bye', 'Happy', 'OK', 'hello', 'hi', 'zoo']
>>> sorted(words, key=mylower)
['Apple', 'Bye', 'Happy', 'hello', 'hi', 'OK', 'zoo']

Setting Multiple Variables

Ok this isn't a trick because I showed this to you earlier. But it's so useful that I want to go over it again because I think most of you didn't digest it.

You can set multiple variables at once if the right-hand side of the assignment operator matches the number of variables on the left. Here are a few toy examples:

a, b, c = [ 'hi', 'hey', 'hiya' ]
name,alpha,co = "chambers 203984 23".split()
average,mean = compute_stats(mydata)   # function returns two values as a tuple or list!

In each of these, you're assignment more than one variable on the left. These can be variable declarations (your first use of them) or over-riding values of variables that already exist. If you don't have the same number on both sides then you'll see an error:

a,b,c = [3, 4, 5, 6]
Traceback (most recent call last):
  File "", line 1, in 
ValueError: too many values to unpack (expected 3)

One of the most useful places to do this is with split(). If you know for sure what's in your string, then you know how many items the split call will return, so you can immediately set custom variables to those values.

Quick List Creation

Create a list with N instances of the same value:

>>> [3]*20
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
>>> ['hi']*10
['hi', 'hi', 'hi', 'hi', 'hi', 'hi', 'hi', 'hi', 'hi', 'hi']

Create a list of ascending integers (old way):

nums = []
for i in range(10):      
    nums.append(i)
print(nums)

Instead you can use what's called "List Comprehension" with a special list syntax:

nums = [i for i in range(10)]
print(nums)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

You can build on this to apply functions to the items as well. Instead of just "i" as the first variable in the expression:

nums = [i*i for i in range(10)]
print(nums)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

List Comprehension

The last couple examples we just showed you use "List Comprehension". List comprehension is a neat and powerful mechanism to filter lists into other lists, as well as perform operations on their values easily. What I just showed you with list creation is the basic starting block, but you can get much more fancy with it.

This page gives a decent overview for those who want to go deeper into it.