NASA Goddard Space Flight Center
Python User Group
2015 Python Boot Camp

Advanced Python

What will be Covered?

  1. List Comprehension
  2. Lambda Function
  3. Exception Handling

Reference Documents

List Comprehension

  • Provides a concise way to create lists.
  • Consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses. The expressions can be anything, meaning you can put in all kinds of objects in lists
  • The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it.
  • Aways returns a result list.

If you used to do it like this:


In [ ]:
new_list = []
for i in old_list:
    if filter(i):
       new_list.append(expressions(i))

You can obtain the same thing using list comprehension:


In [ ]:
new_list = [expression(i) for i in old_list if filter(i)]

Syntax

The list comprehension starts with a '[' and ']', to help you remember that the result is going to be a list.

The basic syntax is


In [ ]:
[ expression for item in list if conditional ]

This is equivalent to:


In [ ]:
for item in list:
    if conditional:
        expression

Here is what it does:


In [ ]:
new_list = [expression(i) for i in old_list if filter(i)]

Examples


In [ ]:
x = [i for i in range(10)]
print x

In [ ]:
# You can either use loops:
squares = []

for x in range(10):
    squares.append(x**2)
 
print squares

# Or you can use list comprehensions to get the same result:
squares = [x**2 for x in range(10)]

print squares

In [ ]:
string = "Hello 12345 World"
numbers = [x for x in string if x.isdigit()]
print numbers

In [ ]:
# Create a function and name it double:
def double(x):
  return x*2

# If you now just print that function with a value in it, it should look like this:
print double(10)

A = [double(x) for x in range(10)]
print A

# You can put in conditions:
B = [double(x) for x in range(10) if x%2==0]
print B

# You can add more arguments:
C = [x+y for x in [10,30,50] for y in [20,40,60]]
print C

In [ ]:
#List comprehensions can contain complex expressions and nested functions:
from math import pi
D = [str(round(pi, i)) for i in range(1, 6)]
print D

In [ ]:
# Calculation of the prime numbers between 1 and 100 using the sieve of Eratosthenes:
n = 100

# Without List Comprehension
#---------------------------
noprimes = [] 
for i in range(2, 8): 
    for j in range(i*2, n, i): 
        noprimes.append(j) 
primes = [] 
for x in range(2, n): 
    if x not in noprimes: 
        primes.append(x)

# With List Comprehension
#------------------------
noprimes = [j for i in range(2, 8) for j in range(i*2, n, i)]
primes = [x for x in range(2, n) if x not in noprimes]
print primes

Lambda, Filter, Reduce and Map

  • The lambda operator or lambda function is a way to create small anonymous functions.
  • These functions are throw-away functions, i.e. they are just needed where they have been created.
  • Lambda functions are mainly used in combination with the functions filter(), map() and reduce().

Basic Syntax of a Lambda Function


In [ ]:
lambda argument_list: expression 

# The argument list consists of a comma separated list of arguments and 
# the expression is an arithmetic expression using these arguments.

In [ ]:
f = lambda x, y : x + y
f(2,1)

Lambda as macro


In [ ]:
line1 = "A cat, a dog  "
line2 = "  a bird, a mountain"

# Use X as an alias for two methods.
x = lambda s: s.strip().upper()

# Call the lambda to shorten the program's source.
line1b = x(line1)
line2b = x(line2)

print(line1b)
print(line2b)

Map Function

map() is a function with two arguments:


In [ ]:
r = map(func, seq)

The first argument func is the name of a function and the second a sequence (e.g. a list) seq. map() applies the function func to all the elements of the sequence seq. It returns a new list with the elements changed by func


In [ ]:
def fahrenheit(T):
    return ((float(9)/5)*T + 32)
def celsius(T):
    return (float(5)/9)*(T-32)
temp = (36.5, 37, 37.5,39)

F = map(fahrenheit, temp)
print F
C = map(celsius, F)
print C

In [ ]:
# map() can be applied to more than one list. 
# The lists have to have the same length.
a = [1,2,3,4]
b = [17,12,11,10]
c = [-1,-4,5,9]
map(lambda x,y:x+y, a,b)

map(lambda x,y,z:x+y+z, a,b,c)

map(lambda x,y,z:x+y-z, a,b,c)

Filter Function

The function filter(func, list) offers an elegant way to filter out all the elements of a list, for which the function func returns True.


In [ ]:
fib = [0,1,1,2,3,5,8,13,21,34,55]
result = filter(lambda x: x % 2, fib)
print result

result = filter(lambda x: x % 2 == 0, fib)
print result

Reduce Function

The function reduce(func, seq) continually applies the function func() to the sequence seq. It returns a single value.


In [ ]:
A = reduce(lambda x,y: x+y, [47,11,42,13])
print A

# Determining the maximum of a list of numerical values by using reduce
f = lambda a,b: a if (a > b) else b
B = reduce(f, [47,11,42,102,13])
print B

# Calculating the sum of the numbers from 1 to 100: 
C = reduce(lambda x, y: x+y, range(1,101))
print C

Exercises

Problem 1


In [ ]:
words = 'The quick brown fox jumps over the lazy dog'.split()
print words
stuff = []
for w in words:
    stuff.append([w.upper(), w.lower(), len(w)])

for i in stuff:
    print i

Use list comprehension and lambda/map function to define the variable stuff.


In [ ]:

Problem 2


In [ ]:
# We want to simulate a series of coin tosses where 0 is heads and 1 is tails.
from random import random
n = 10
results = [] 
for x in range(n): 
    results.append(int(round(random())))

print results

Use a list comprehension to make it more concise.


In [ ]:

Problem 3

Use list comprehension to remove all the vowels from the sentence


In [ ]:
sentence = "The GFSC Python Bootcamp is a great opportunity to learn Python programming."
vowels = 'aeiou'

In [ ]:

Exception Handling


In [ ]:
from IPython.display import YouTubeVideo
YouTubeVideo("hrR0WrQMhSs")
  • An exception is an error that happens during the execution of a program.
  • Exceptions are known to non-programmers as instances that do not conform to a general rule.
  • Exception handling is a construct to handle or deal with errors automatically.
  • The code, which harbours the risk of an exception, is embedded in a try block.

Simple example


In [ ]:
def enter_number0():
    n = int(raw_input("Please enter a number: "))

enter_number0()

In [ ]:
def enter_number1():
    while True:
        try:
           n = raw_input("Please enter an integer: ")
           n = int(n)
           break
        except ValueError:
            print "No valid integer! Please try again ..."
    print "Great, you successfully entered an integer!"

enter_number1()

Some Exception Errors

  • IOError: The file cannot be opened
  • ImportError: Python cannot find the module
  • ValueError: A built-in operation or function receives an argument that has the right type but an inappropriate value.
  • KeyboardInterrupt: The user hits the interrupt key (normally Control-C or Delete)
  • EOFError: One of the built-in functions (input() or raw_input()) hits an end-of-file condition (EOF) without reading any data.
  • OverflowError, ZeroDivisionError, FloatingPointError:

else...


In [ ]:
def inverse_number0():
    try:
        x = float(raw_input("Your number: "))
        inverse = 1.0 / x
    except ValueError:
        print "You should have given either an int or a float"
    except ZeroDivisionError:
        print "Infinity"
    else:
        print "OK"
        
inverse_number0()

In [ ]:
# import module sys to get the type of exception
import sys

def inverse_number1():
    while True:
        try:
            x = int(raw_input("Enter an integer: "))
            r = 1/x
            break
        except:
            print "Oops!",sys.exc_info()[0],"occured."
            print "Please try again."
            print
    print "The reciprocal of",x,"is",r
    
inverse_number1()

Clean-up Actions (try ... finally)


In [ ]:
def inverse_number2():
    try:
        x = float(raw_input("Your number: "))
        inverse = 1.0 / x
    finally:
        print "There may or may not have been an exception."
    print "The inverse: ", inverse
    
inverse_number2()

In [ ]:
def inverse_number3():
    try:
        x = float(raw_input("Your number: "))
        inverse = 1.0 / x
    except ValueError:
        print "You should have given either an int or a float"
    except ZeroDivisionError:
        print "Infinity"
    finally:
        print "There may or may not have been an exception."
    
inverse_number3()

Raising Exceptions


In [13]:
def achilles_arrow(x):
    if abs(x - 1) < 1e-3:
        raise StopIteration
    x = 1 - (1-x)/2.
    return x

In [14]:
x=0.0

while True:
    try:
        x = achilles_arrow(x)
    except StopIteration:
        break
        
print "x = ", x


x =  0.9990234375

In [ ]: