LECTURE 3 Basic Python: Part 2

advertisement

LECTURE 3

Basic Python: Part 2

OVERVIEW

More Functions

Data Structures

Introduction to Modules

FUNCTIONS

We’ve already know the basics of functions so let’s dive a little deeper.

• Default argument values

• We can provide a default value for any number of arguments in a function.

• Allows functions to be called with a variable number of arguments.

def connect(uname, pword, server = 'localhost', port = 9160):

# connecting code

• This function can be called a number of ways. connect('admin', 'ilovecats') connect('admin', 'ilovecats', 'shell.cs.fsu.edu') connect('admin', 'ilovecats', 'shell.cs.fsu.edu', 6379)

FUNCTIONS

When functions arguments are not specified, they are called positional arguments.

Keyword arguments are of the form kwarg = value

. connect('admin', pword = 'ilovecats', server = 'shell.cs.fsu.edu', port = 6379)

If keyword arguments are used they must follow any positional arguments, although the relative order of keyword arguments is unimportant.

Parameters of the form

*param contain a variable number of arguments within a tuple. Parameters of the form

**param contain a variable number of keyword arguments.

FUNCTIONS

def connect(uname, *args, **kwargs): print uname for arg in args: print arg for key in kwargs.keys(): print key, ": ", kwargs[key] connect('admin', 'ilovecats', server='localhost', port=9160)

Output: ?

FUNCTIONS

def connect(uname, *args, **kwargs): print uname for arg in args: print arg for key in kwargs.keys(): print key, ": ", kwargs[key] connect('admin', 'ilovecats', server='localhost', port=9160)

Output: admin ilovecats port : 9160 server : localhost

DATA STRUCTURES

Advanced List Usage

Tuples

Sets

Dictionaries

Looping

ADVANCED LISTS

We’ve already reviewed basic list usage and seen some of the built-in functionality.

• Stacks

• Last in, first out.

>>> mystack = [1, 2, 3, 4, 5]

>>> mystack.append(6)

>>> mystack

[1, 2, 3, 4, 5, 6]

>>> mystack.pop()

6

>>> mystack

[1, 2, 3, 4, 5]

ADVANCED LISTS

• Queues

• First in, first out.

• Use collections.deque for fast pops from the beginning.

>>> from collections import deque

>>> myqueue = [1, 2, 3, 4, 5]

>>> myfastqueue = deque(myqueue)

>>> myfastqueue deque([1, 2, 3, 4, 5])

>>> myfastqueue.append(6)

>>> myfastqueue deque([1, 2, 3, 4, 5, 6])

>>> myfastqueue.popleft()

1

>>> myfastqueue deque([2, 3, 4, 5, 6])

FUNCTIONAL PROGRAMMING TOOLS

Lists can be used with a few useful functions to implement functional programming.

• filter()

• filter(function, sequence) filters items from sequence for which function(item) is true.

• Returns a string or tuple if sequence is one of those types, otherwise result is a list. def even(x): if x % 2 == 0: return True else: return False print(filter(even, range(0,30)))

Output: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]

FUNCTIONAL PROGRAMMING TOOLS

• map()

• map(function, sequence) applies function to each item in sequence and returns the results as a list.

• Multiple arguments can be provided if the function supports it. def square(x): return x**2 print(map(square, range(0,11))) def square(x, y): return x*y print(map(square, range(0, 11), range(0,11)))

Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

FUNCTIONAL PROGRAMMING TOOLS

• reduce()

• reduce(function, sequence) returns a single value computed as the result of performing function on the first two items, then on the result with the next item, etc.

• There’s an optional third argument which is the starting value. def factorial(x, y): return x*y print(reduce(factorial, range(1,5)))

Output: 24

FUNCTIONAL PROGRAMMING TOOLS

One can also define lambda functions within Python.

• Use the keyword lambda instead of def.

• Can be used wherever function objects are used.

• Restricted to one expression.

>>> print(map(lambda x: x**2, range(0,11)))

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

LIST COMPREHENSIONS

List comprehensions provide a nice way to construct lists where the items are the result of some operation.

The simplest form of a list comprehension is: [ expr for x in sequence ].

Any number of additional for and/or if statements can follow the initial for statement.

A simple example of creating a list of squares.

>>> squares = [x**2 for x in range(0,11)]

>>> squares

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 ]

LIST COMPREHENSIONS

Here’s a more complicated example which creates a list of tuples.

>>> squares = [(x, x**2, x**3) for x in range(0,11) if x % 2 == 0]

>>> squares

[(0, 0, 0), (2, 4, 8), (4, 16, 64), (6, 36, 216), (8, 64, 512), (10, 100, 1000)]

The initial expression in the list comprehension can be anything, even another list comprehension.

>>> [[x*y for x in range(1,5)] for y in range(1,5)]

[[1, 2, 3, 4], [2, 4, 6, 8], [3, 6, 9, 12], [4, 8, 12, 16]]

TUPLES

Tuples are very similar to lists except for two main points:

• Enclosed by parentheses.

• Immutable (but can contain mutable objects).

• Packing a tuple:

Unpacking a tuple:

>>> mytuple = 1, "two", [3, "four"]

>>> mytuple

(1, 'two', [3, 'four'])

>>> mytinytuple = "atom",

>>> mytinytuple

('atom',)

>>> a, b, c = mytuple

>>> print a, b, c

1 two [3, 'four']

SETS

Sets are an unordered collection of unique elements. We’ve already seen some set basics, but it is important to note that sets also support set comprehensions.

>>> a = {x for x in 'alphabet'}

>>> a set(['a', 'b', 'e', 'h', 'l', 'p', 't'])

DICTIONARIES

Dictionaries support dict comprehensions as well.

>>> squares_dict = {x: x**2 for x in range(1,11)}

>>> squares_dict

{1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100}

MODULES

A module is a file containing Python code. Our Fibonacci code file from the previous lecture could be a module.

Modules are referenced by their filename (minus the .py suffix). For example, fib.py can be referenced as “fib”. This is also available through the __name__ variable.

Modules are included using the import keyword. Functions defined in a module are available as a method of the imported module.

>>> import fib

>>> fib.even_fib(4000000)

4613732

MODULES

It is important to note that executable statements in a module will execute when it is first imported.

Let’s say I create a module (greeting.py) which contains the following code: greeting.py

def greet(): print("Hello from a function!") print "Hello!"

>>> import greeting

Hello!

>>> greeting.greet()

Hello from a function!

MODULES

By convention, all import statements should appear at the top of the .py file.

It is possible to import specific objects from a module. For example,

>>> from greeting import greet

Hello!

>>> greet()

Hello from a function!

Use from module import * to import all objects from a module.

MODULES

When a module is imported, the interpreter will first search for a built-in module with the same name. If that fails, then it will search for the module in the list of directories given by the sys.path

variable.

>>> import sys

>>> sys.path

['', '/usr/local/lib/python2.7/dist-packages/D_Wave_One_Python_Client-1.4.1-py2.6-linuxx86_64.egg', '/usr/local/lib/python2.7/dist-packages/PyOpenGL-3.0.2a5-py2.7.egg',

'/usr/local/lib/python2.7/dist-packages/pip-1.1-py2.7.egg', '/usr/local/lib/python2.7/distpackages/Sphinx-....

LEXICOGRAPHIC PERMUTATIONS

Let’s use what we’ve learned today to solve another problem in Python.

A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2,

3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:

012 021 102 120 201 210

What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?

driver.py

LEXICOGRAPHIC PERMUTATIONS

permute.py

from __future__ import print_function from permute import gen_permutation from itertools import permutations if __name__ == "__main__": num_digits = raw_input("Number of digits: ") digit_index = raw_input("Index of the permutation: ") result = gen_permutation(int(num_digits), int(digit_index)) print(result) def factorial(num):

# Returns the factorial of num return reduce(lambda x,y: x*y, [x for x in range(1,num+1)]) def gen_permutation(n, i):

# Find the first digit of the desired permutation f = factorial(n-1) first_digit = i/f

$ python driver.py

Number of digits: 10

Index of the permutation: 1000000

2783915460

# Calculate the permutations of the remaining digits rest_digits = [str(x) for x in range(0,n) if x != first_digit] perm_list = [''.join(x) for x in (permutations(rest_digits))]

# Construct the desired permutation i = i - first_digit*f return(int(str(first_digit) + perm_list[ i-1 ]))

NEXT LECTURE

I/O

Files

Errors and Exceptions

Download