Functions

  • Define the function using def keyword.
  • to return a value using return keyword

In [1]:
def square(x):
    return x * x

print square(10)


100
  • even no return inside the function, function still return None

In [2]:
def logging(message):
    print 'Message:', message
    
print logging('Hello world')


Message: Hello world
None
  • function name is a variable

In [3]:
print square


<function square at 0x10de8db18>

In [4]:
power2 = square
print power2(10)


100

Default arguments

  • specify a default value for one or more arguments

In [5]:
def exponential(x, base=2):
    value = 1
    for i in range(x):
        value = value * base

    return value

print exponential(10)
print exponential(2, 3)


1024
9
  • non-default argument cannot follow after default argument

In [6]:
def exp(base=2, x):
    return exponential(x, base)


  File "<ipython-input-6-c36fe27b5bfa>", line 1
    def exp(base=2, x):
SyntaxError: non-default argument follows default argument
  • Important: the default value is evaluated only once, which means the default value is shared between subsequent calls

In [7]:
def append2list(value, array=[]):
    array.append(value)
    return array

print append2list(1)
# get [1, 2] instead of [1] because the default value is shared between first call
print append2list(2)


[1]
[1, 2]

Keyword arguments

  • function can be called using keyword arguments of the form key_word_argument=value

In [8]:
def pet_color(dog, cat='black', pig='pink'):
    print 'Dog color:', dog, '. Cat color:', cat, '. Pig color:', pig

In [9]:
pet_color('yellow')


Dog color: yellow . Cat color: black . Pig color: pink

In [10]:
pet_color(dog='white')


Dog color: white . Cat color: black . Pig color: pink

In [40]:
pet_color('white', pig='blue')


Dog color: white . Cat color: black . Pig color: blue

In [12]:
pet_color(cat='blue', dog='white')


Dog color: white . Cat color: blue . Pig color: pink
  • when calling a function, keyword value cannot be precedent non-keyword (positional) value

In [13]:
pet_color('white', cat='blue', 'pink')


  File "<ipython-input-13-bbc6d8693b17>", line 1
    pet_color('white', cat='blue', 'pink')
SyntaxError: non-keyword arg after keyword arg

Exercise

Calculate matrix vector product between A and x. You should to use function concept.

A = [ [-3, -2, -1], [2, 3, 0], [1, 4, 5], [6, 7, 8] ] x = [7, 3, 1]

Hint: define function which calculates dot product between vector


In [46]:
A = [
    [-3, -2, -1],
    [2, 3, 0],
    [1, 4, 5],
    [6, 7, 8]
]
x = [7, 3, 1]


def dot(x, y):
    res = 0
    for i in xrange(len(x)):
        res += x[i] * y[i]
    
    return res
    
result = []
for i in xrange(len(A)):
    result.append(dot(A[i], x))

print result


[-28, 23, 24, 71]

Arbitrary arguments

  • Way to specify a function can be called with an arbitrary number of arguments

In [27]:
def sum_square(*args):
    total = 0
    for no in args:
        total += no ** 2
    return total

print sum_square()
print sum_square(1, 2)
print sum_square(1, 2, 3)


0
5
14
  • Can do with keyword arguments too

In [26]:
def print_name(**kwargs):
    for kw in kwargs.keys():
        print kw, ':', kwargs[kw]
        
print_name(foo='bar', foo2='bar2')


foo : bar
foo2 : bar2
  • Can mix too
  • Positional argument must define before keyword argument

In [24]:
def print_arg(required_arg, *args, **kwargs):
    pass

In [25]:
def print_arg(required_arg, **kwargs, *args):
    pass


  File "<ipython-input-25-fbb97136a039>", line 1
    def print_arg(required_arg, **kwargs, *args):
                                        ^
SyntaxError: invalid syntax

Unpacking arguments

  • When the arguments are already in a list or tuple, use * to unpack arguments

In [36]:
range(3, 6)


Out[36]:
[3, 4, 5]

In [37]:
args = [3, 6]
print range(*args)


[3, 4, 5]
  • dictionaries can deliever keyword arguments with ** operator

In [39]:
d = {'cat': 'white', 'pig': 'blackwhite'}
print pet_color('brown', **d)


Dog color: brown . Cat color: white . Pig color: blackwhite
None

Lambda expression

  • define small anonymous function using lambda keyword

In [14]:
prod = lambda a, b: a * b

print prod(5, 2)


10

In [28]:
def compute(a, b, operator):
    return operator(a, b)

print compute(5, 2, lambda a, b: a + b)
print compute(5, 2, lambda a, b: a * b)


7
10

Functional programming tools

3 built-in functions that are very useful when used with sequence type: map, filter, reduce

  • map(function,sequence): call function(item) for each of the sequence's items and returns a list of the return values.

In [34]:
print map(lambda x: x ** 2, range(0, 5))


[0, 1, 4, 9, 16]
  • filter(function, sequence): return a list contains items from sequence for which function(item) is true

In [33]:
print range(-5, 5)
print filter(lambda x: x > 0, range(-5, 5))


[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
[1, 2, 3, 4]
  • reduce(function, sequence): return a single value constructed by calling the binary function function on the first two items of the sequence, then on the result and the item, and so on.
  • reduce(function, sequence, init_value): when init_value is provide, the binary function function will be called on the init_value and the first item of the sequence, then on the result and the next item, and so on.

This is the picture describe the reduce process


In [35]:
print reduce(lambda a, b: a + b, [47, 11, 42, 13])


113

In [44]:
reduce(lambda a, b: a + b, [47, 11, 42, 13], -1)


Out[44]:
112