Python lecture 04
Upcoming SlideShare
Loading in...5
×
 

Python lecture 04

on

  • 83 views

 

Statistics

Views

Total Views
83
Views on SlideShare
83
Embed Views
0

Actions

Likes
0
Downloads
2
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Python lecture 04 Python lecture 04 Presentation Transcript

  • Python & Perl Lecture 04 Department of Computer Science Utah State University
  • Outline ● ● ● ● ● Types in Python Built-in Sequences List: Python's Workhorse Function parameters Scoping
  • Types in Python
  • Strong and Dynamic Typing ● ● ● ● ● Python is both strongly and dynamically typed Strong typing means that every object has a specific type Variables contain references to objects Dynamic typing means that types of objects pointed to by variables are inferred at run time There is no contradiction b/w strong and dynamic typing: they describe two different features of programming languages
  • Strong and Dynamic Typing var = 10 var = 'hello' ● So hasn't var just changed type ? ● The answer is NO. var isn't an object at all - it's a name.
  • Duck Typing ● ● ● ● Sometimes Python is called a duck typing language The gist of duck typing: real types of objects do not matter so long as specific operations can be performed on them Objects themselves “know” whether they can be added, multiplied, concatenated, etc If and when objects cannot perform a requested operation, a run-time error occurs
  • Checking Object Types ● There are two methods in Python for checking object types: type(<object>) and isinstance(<object>, <type>) >>> type([1, 2]) <type 'list'> >>> isinstance([1, 2], list) True >>> type((1, 2)) <type 'tuple'> >>> isinstance((1, 2), tuple) True >>> isinstance((1, 2), type((1, 2))) True
  • Built-In Sequences
  • Python Built-In Sequences ● There are six sequences in Python:  list  tuple  string (str)  unicode string (unicode)  buffer  xrange
  • Lists
  • General Facts ● Lists are mutable type sequences ● Lists contain 0 or more references to objects ● Lists can contain references to different types of objects
  • Construction # lst1 is an empty list >>> lst1 = [] >>> lst1 [] # lst2 is a list of integers. >>> lst2 = [1, 2, 3, -4, 0, -5, 7] >>> lst2 [1, 2, 3, -4, 0, -5, 7]
  • Construction # lst3 is a mixed list. >>> lst3 = [1, 'a', 'rock violin', 3.14, "math"] >>> lst3 [1, 'a', 'rock violin', 3.14, 'math'] # lst4 is a nested list. >>> lst4 = [1, [2, 3], 4, 5] # lst5 is another nested list. >>> lst5 = [1, lst3] >>> lst5 [1, [1, 'a', 'rock violin', 3.14, 'math']]
  • Construction ● list() function can be used as a constructor to make empty lists or convert other sequences to lists >>> x = list() >>> x [ ] >>> y = list(“abc”) >>> y ['a', 'b', 'c']
  • Sequence Operations ● All sequences support the following operations:  Indexing  Membership  Concatenation  Multiplication  Slicing  Length  Minimum/Maximum element
  • Indexing ● ● Use the square brackets [ and ] to index into lists Since lists are sequences, left-to-right indexing starts at 0 >>> lst = [1, 2, 3] >>> lst[0] 1 >>> lst[1] 2 >>> lst[2] 3
  • Side Note on Sequence Indexing ● ● ● In Python sequences, elements can be indexed left to right and right to left If s is a sequence, then the leftmost element is s[0] while the rightmost element is s[-1] In general, if s is a sequence of n elements, then s[0] == s[-n], s[1] == s[-n+1], …, s[n-1] == s[-1]
  • Sequence Indexing Example >>> s = ['a', 'b', 'c', 'd', 'e'] ### s is a list of 5 characters >>> s[0] == s[-5] ### s[0] == s[-5] == 'a' True >>> s[1] == s[-5+1] == s[-4] ### s[1] == s[-4] == 'b' True >>> s[2] == s[-5+2] == s[-3] ### s[2] == s[-3] == 'c' True >>> s[3] == s[-5+3] == s[-2] ### s[3] == s[-2] == 'd' True >>> s[4] == s[-5+4] == s[-1] True ### s[4] == s[-1] == 'e'
  • Indexing ● Right-to-left indexing starts with -1 and ends with -n, where n is the number of elements in the list >>> lst = [1, 2, 3] >>> lst[-1] # 1st element from right 3 >>> lst[-2] # 2nd element from right 2 >>> lst[-3] # 3rd element from right 1
  • Out of Range Indexing ● Both positive and negative indices result in errors if they go off on either side of the list >>> lst = [1, 2, 3] >>> lst[3] out of range error >>> lst[-4] out of range error
  • Membership ● If x is an object and lst is a list, then x in lst returns True if x is an element of lst, else False is returned >>> lst = [10, 'eggs', 3] >>> 10 in lst True >>> 'eggs' in lst True >>> 'buzz' in lst False
  • Membership ● If x is an object and lst is a list, then x not in lst returns True if x is not an element of lst, else False >>> lst = [10, 'eggs', 3] >>> 11 not in lst True >>> 'eggs' not in lst False >>> 'buzz' not in lst True
  • Membership ● Membership can be tested on nested lists >>> lst = [['one', 1], ['two', 2], ['three', 3]] >>> ['one', 1] in lst True >>> ['two', 2] in lst True >>> ['three', 3] in lst True
  • Side Note On NOT ● If you want to test if the negation of a boolean expression is true or false, you can use not in front that expression >>> not 1 == 2 True >>> not 1 == 1 False >>> lst=[1,2,3] >>> 4 not in lst True >>> 1 != 2 ## this works as well
  • Concatenation ● If x and y are lists, then x + y is their concatenation, i.e. the list that consists of x's elements followed by y's elements >>> x = [10, 'eggs', 3] >>> y = [12, 'buzz', 5] >>> z = x + y >>> z [10, 'eggs', 3, 12, 'buzz', 5]
  • Multiplication ● If x is a list and n is an integer, then x * n or n * x is the list that consists of n copies (copies of references to x) of x >>> x = [1, 2] >>> y = ['a', 'b'] >>> z = [x, y] >>> z [[1, 2], ['a', 'b']] >>> z2 = z * 2 >>> z2 [[1, 2], ['a', 'b'], [1, 2], ['a', 'b']]
  • Slicing ● ● ● ● Slicing is an operation that accesses a range of elements in a sequence When the length of the range is 1, slicing is equivalent to indexing A Slice is defined by two indexes: the start index is the index of the first element; the end index is the index of the first element that immediately follows the last element of the slice The start index is inclusive and the end index is exclusive
  • Slicing Example >>> lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] >>> lst[0:1] ['a'] >>> lst[0:2] ['a', 'b'] >>> lst[1:2] ['b'] >>> lst[3:7] ['d', 'e', 'f', 'g']
  • ● Omission of both indexes slices the entire list Slicing >>> lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] >>> lst[:] ## same as lst[0:7] ['a', 'b', 'c', 'd', 'e', 'f', 'g'] ● Omitted start index defaults to 0 >>> lst[:3] ## same as lst[0:3] ['a', 'b', 'c'] ● Omitted end index defaults to the one right after the last index in the sequence >>> lst[3:] ## same as lst[3:7] ['d', 'e', 'f', 'g']
  • Length, Minimum, Maximum ● These are self explanatory >>> >>> 3 >>> 'a' >>> 'c' lst = ['a', 'b', 'c'] len(lst) min(lst) max(lst)
  • Multi-Dimensional Lists ● It is possible to construct multi-dimensional lists ● Here is an example of a 2D list (aka matrix) >>> matrix = [[0, 1, 2], [3, 4, 5], [6, 7, 8]] >>> matrix[0] [0, 1, 2] >>> matrix[1] [3, 4, 5] >>> matrix[0][0] 0 >>> matrix[0][2] 2
  • Deleting Elements ● Delete individual element >>> lst = [1, 2, 3, 4, 5] >>> del lst[1] ## deleting 2 >>> lst [1, 3, 4, 5] ● Delete a slice >>> del lst[1:3] >>> lst [1, 5] ● Assign an empty list to a slice to delete it >>> lst[0:2] = []
  • List Manipulation with Built-In Methods append(), extend(), reverse(), remove(), index(), count(), sort()
  • list.append() ● The method append() adds an object at the end of the list >>> lst1 = [1, 2, 3] >>> lst1.append('a') >>> lst1 [1, 2, 3, 'a'] >>> lst1.append(['b', 'c']) >>> lst1 [1, 2, 3, 'a', ['b', 'c']]
  • list.extend() ● The method extend() also destructively adds to the end of the list, but, unlike append(), does not work with non-iterable objects >>> lst1 = [1, 2, 3] >>> lst1.extend(4) # error >>> lst1.extend(“abc”) >>> lst1 [1, 2, 3, 'a', 'b', 'c']
  • list.append() vs. list.extend() ● Here is another difference b/w extend() and append(): >>> lst1 = [1, 2, 3] >>> lst1.append(['a', 'b']) >>> lst1 [1, 2, 3, ['a', 'b']] ### the last element is a list >>> lst1 = [1, 2, 3] >>> lst1.extend(['a', 'b']) >>> lst1 [1, 2, 3, 'a', 'b'] ### ['a', 'b'] is added at the end of ### lst1 element by element
  • len(), list.count(), list.index() ● Let lst be a list ● lst.len() returns the length of lst ● lst.count(x) returns number of i's such that s[i] == x ● ● lst.index(x, [i, [,j]]) returns smallest k for which s[k] == x and i <= k < j Python documentation note: the notation [i, [, j]] means that parameters i and j are optional: they can both be absent, one of them can be absent, or they can both be present
  • len(), list.count(), list.index() >>> lst = ['a', 'a', 1, 1, 1, 'b', 2, 2, 3] >>> len(lst) 9 >>> lst.count('a') 2 >>> lst.count(1) 3 >>> lst.index('a', 0, 2) 0 >>> lst.index('a', 1, 2) 1 >>> lst.index('a', 2) ValueError: list.index(x): x not in list
  • list.remove(), list.reverse() ● Let lst be a list ● lst.remove(x) is the same as del lst[lst.index(x)] ● lst.reverse() reverses lst in place ● lst.reverse() does not return a value
  • list.remove(), list.reverse() >>> lst = [1, 2, 3, 4, 5] >>> lst.remove(1) >>> lst [2, 3, 4, 5] >>> lst = [1, 2, 3, 4, 5] >>> del lst[lst.index(1)] >>> lst [2, 3, 4, 5] >>> lst.reverse() >>> lst [5, 4, 3, 2]
  • Function Parameters
  • Types of Parameters ● ● ● There are two types of parameters in Python: positional and keyword Positional parameters are regular parameters in the function signature: the values they receive are determined by their position in the signature Keyword parameters are parameters that can take on default values and whose position can vary in the functional signature
  • Positional Parameters: Example def hw_avail_str(crsn, hwn, hw_loc, due_date, submit_loc): print "%s Assignment %s is available at %s. It is due by %s in %s." % (crsn, hwn, hw_loc, due_date, submit_loc) >>> hw_avail_str('CS3430', '2', 'www.canvas.org', '11:59pm, Jan 25, 2014', 'your canvas') CS3430 Assignment 2 is available at www.canvas.org. It is due 11:59pm, Jan 25, 2014 in your canvas . ● Note: You have to remember the position of each parameter in the signature, i.e., that crsn (course number) comes first, hwn (homework number) comes second, hw_loc (homework web location) comes third, etc.
  • Keyword Parameters: Example def hw_avail_str2(crsn='CS3430', hwn='0', hw_loc='www.myblog.org', due_date='', submit_loc='your canvas'): print "%s Assignment %s is available at %s. It is due by %s in %s." % (crsn, hwn, hw_loc, due_date, submit_loc) >>> hw_avail_str2(hwn='2', due_date='11:59pm, Jan 25, 2014') CS3430 Assignment 2 is available at www.myblog.org. It is due by 11:59pm, Jan 25, 2014 in your canvas. ● Note: You do not have to remember the position of each parameter in the signature but you do have to remember the name of each keyword parameter
  • Combining Positional & Keyword Parameters ● Positional & keyword parameters can be combined in one signature: positional parameters must precede keyword parameters def combine(x, y=10, z='buzz'): print 'x=%d y=%d z=%s' % (x, y, z) >>> combine(5) x=5 y=10 z=buzz >>> combine(5, y=50, z='foo') x=5 y=50 z=foo
  • Positional Parameter Collection ● ● ● ● What happens if you do not know how many parameter values you receive on the input? There are two choices: use a container, e.g., a list or a tuple, or use *operator Suppose that we want to write a function that applies three types of operations: sum, min, and max to sequences We can use *operator to solve this problem
  • Applying Operations to Parameter Collections def apply_oper(oper_name, *params): if oper_name == 'sum': return sum(params) elif oper_name == 'min': if len(params) > 0: return min(params) else: return None elif oper_name == 'max': if len(params) > 0: return max(params) else: return None else: return 'Unknown operation ' + oper_name
  • Applying Operations to Parameter Collections >>> apply_oper('sum', 1, 2) 3 >>> apply_oper('sum', 1, 2, 3) 6 >>> apply_oper('sum') 0 >>> apply_oper('min', 1, 2, 3) 1 >>> apply_oper('max', 1, 2, 3, 4, 5) 5 >>> apply_oper('max')
  • Scoping
  • Scope ● ● ● Scopes (aka namespaces) are dictionaries that map variables to their values Builtin function vars() returns the current scope Python documentation recommends against modifying the returned value of vars() because the results are undefined
  • Scope ● def always introduces a new scope ● Here is a quick def scoping example: >>> x = 10 >>> def f(y): x = y ## changes x to y only inside f print 'x=%d'%x >>> f(20) >>> x ## we are outside the scope of f so x is 10 10
  • Scope ● It is possible to change the value of a global variable inside a function: all you have to do is to tell Python that the variable is global def change_x_val(z): global x x=z >>> x = 1 >>> change_x_val(10) >>> x 10
  • Scope Sensitivity of vars() ● Calls to vars() are scope-sensitive and return the currently active scopes def local_vars2(x, y): def local_vars3(n, m): n=x+1 m=y+2 print 'vars() inside local_vars3' print vars() z = x + 10 w = y + 20 print 'vars() inside local_vars2' print vars() local_vars3(3, 4)
  • Scope Sensitivity of vars() >>> local_vars2(1, 2) vars() inside local_vars2 {'y': 2, 'x': 1, 'local_vars3': <function local_vars3 at 0x020B10B0>, 'z': 11, 'w': 22} vars() inside local_vars3 {'y': 2, 'x': 1, 'm': 4, 'n': 2}
  • Global Scope ● ● Builtin function globals() returns the global scope regardless of what the current scope is For example, the following function prints the global scope def global_vars(x, y): z=x+1 w=y+2 print globals()
  • Global Scope ● This function prints the global scope several times despite the scope nestings def global_vars2(x, y): def global_vars3(n, m): n=x+1 m=y+2 print 'globals() inside global_vars3', globals() z = x + 10 w = y + 20 print 'globals() inside global_vars2', globals() global_vars3(3, 4)
  • Nested Scopes ● Nested scopes are very useful in functions that return other functions def func_factory(oper, lst): def list_extender(inner_lst): inner_lst.extend(lst) def list_remover(inner_lst): for i in lst: inner_lst.remove(i) if oper == 'extend': return list_extender elif oper == 'remove': return list_remover else: return 'ERROR: Unknown operation'
  • Nested Scopes ● Nested scopes are very useful in functions that return other functions >>> fex = func_factory('extend', ['I', 'am', 'extended']) >>> frm = func_factory('remove', ['I', 'am', 'extended']) >>> lst = [1, 2, 3] >>> fex(lst) ## lst is extended by ['I', 'am', 'extended'] >>> lst [1, 2, 3, 'I', 'am', 'extended'] >>> frm(lst) ## all elements of ['I', 'am', 'extended'] are removed from lst >>> lst [1, 2, 3]
  • Reading & References ● www.python.org ● http://docs.python.org/library/stdtypes.html#typesseq ● doc.python.org/howto/unicode.html ● Ch 02, M. L. Hetland. Beginning Python From Novice to nd Professional, 2 Ed., APRESS