//
you're reading...
Uncategorized

Python Iterators, Containers, Sequences and Mappings

Objects First

Python is a language that in many aspects is organized around the “for-loop”. Python defines a protocol for what that means for a class of objects using the name iterable. The iterators produced by iterables provide the main abstraction for a data stream container and these pervade professional python code. They are also a great place to start learning the language of python. So let’s jump in and start talking about some classes of objects called sequences and mappings.

Python Sequences: FilesStringsTuples, Lists,  Dictionaries

These are all iterable objects designed with a protocol to be usable in for loops.

Files are objects that exist outside your program in secondary memory and are considered persistent . When a file is opened using the python open command, the system returns a file handle that provides a reference to the data for the file.  We use a for loop to read through and count each of the lines in a file, as Python takes care of splitting the data in the file into separate lines using the newline character as delimiter:

fhand = open('myfile.txt')
count = 0
for line in fhand:
    count = count + 1
print 'Line Count:', count
#print line

If you know the file is relatively small compared to the size of your main memory, you can read the whole file into one string using the .read() or .readlines() methods on the file handle. The variable inputstring in the following code is of string type which is iterable, of course.

fhand = open('myfile-short.txt')
inputlines = fhand.readlines()
for line in inputlines:
    print line

fhand.close() # Careful - files must be reset to be read twice
fhand = open('myfile-short.txt')
inputstring = fhand.read()
for c in inputstring:
    print c

Strings, tuples and lists.   A major difference between these iterable types is that strings and tuples are immutable, but lists are mutable. String literals are written in single or double quotes: 'xyzzy', "frobozz".

Strings of length 0, 1 , 2, etc: ”, ‘1 ‘, “1 2”, ‘hello\n’

Tuples  of length 0, 1 , 2, etc: () (1, ) (1 , a) Parentheses are optional if len > 0. Parentheses are optional, so that is why a 1-tuple requires a comma.

Tuples are immutable and are used in software that models heterogeneous sequences, while lists are mutable and are used in software that models homogeneous sequences.

Lists of length 0, 1 , 2, etc: [] [1] [1 ,2] [1,2,3]

Indexing is 0-based. Negative indices (usually ) mean count backwards from end of sequence.
Sequence slicing [starting-at-index : but-less-than-index [ : step]]. Start defaults to 0, end to len(sequence), step to 1.

#In Class exercises 1/14/15 
# Create a string with your name"
myname = "Prof Fred A"

#Create a tuple of immutable profile data
myemail = "annexsfs@ucmail.uc.edu"
myyob= 1970
mysocsec= "123-45-6789"
myImmuTuple= (myname, myemail, myyob, mysocsec)

#Create a list of mutable profile data
myoffice = "811B Old Chem"
myphone = 5135561807
myage = 2015 - myyob
myMutList =  [myage, myphone, myoffice]

#Create a dictionary of mutable profile data
myDict = { "job title": "Professor", "relationship status": "Happily Married",
           "health status": "Need to workout"} 

# Use for loops to iterate over each data structure
for c in myname:
   print "Current letter: ", c
   
for i in myMutList:
     print "Current list-elt: ",  i

for t in myImmuTuple:
    print "Current tup-elt:", t
    
for k in myDict:
    print k,":", myDict[k]
 
# OK to mutate list
# mylist[0]= "Bozo the Clown"
# Error if we try to mutate string or tuple
# myname[0]='J' =>; TypeError: 'str' object does not support item assignment 
# myImmuTuple[0] = "Bozo the Clown"  =>; TypeError: 'tuple' object does not support item assignment

Strings, Lists and Tuples: Indexing and Slicing
Python strings, lists, and tuples can reference their individual items (characters in case of strings) or sub-strings or sub-lists using square-bracket notation.
Individual characters/item are indexed with single number position, and slices or substrings use the starting position and ending positions of the piece we want.

#Example showing how to slice and print sub-strings
var1 = 'Hello World!'
var2 = 'Python';
print 'var1[0]: ', var1[0] # prints var1[0]:  H
print 'var2[1:5]: ', var2[1:5]    # prints var2[1:5]:  ytho

#immutable sequence- type tuple

a = (0,1,2,3,4,5,6,7)
for i in a:   
    print 'Current tuple item: ', i 

#Examples showing how to slice tuples
a[3] == 3
a[-1] == 7
a[2:4] == (2, 3)
a[1:] == (1, 2, 3, 4, 5, 6, 7)
a[:3] == (0, 1, 2)
a[:] == (0,1,2,3,4,5,6,7) # makes a copy of the sequence.
a[::2] == (0, 2, 4, 6)    # Only even numbers.
a[::-1] = (7, 6, 5, 4, 3 , 2, 1, 0) # Reverse order. 

#mutable sequence-type list
lst = [0,1,2,3,4,5,6,7]

for i in lst:   
    print 'Current list item: ', i 

#Examples showing how to modify/mutate lists
s[i] = x         # item i of s is replaced by x
s[i:j] = t       # slice of s from i to j is replaced by the contents of the iterable t
del s[i:j]       # same as s[i:j] = []
s.append(x)
s.extend(x)
                 #Example
s=[1,2,3];
# s.extend(4)->; Type Error
# s.extend([4]) or s.append(4) ->; s=[1,2,3,4]
s.count(x)      # return number of i‘s for which s[i] == x
s.index(x)      # return smallest k such that s[k] == x
s.insert(i, x)  # same as s[i:i] = [x]
s.pop([i])      # same as x = s[i]; del s[i]; return x
s.remove(x)     # same as del s[s.index(x)]
s.reverse()     # reverses the items of s in place
s.sort([cmp[, key[, reverse]]])   # sort the items of s in place 

Dictionaries (Mapping types) Dictionaries (type dict) of length 0, 1 , 2, etc: {key: value} {1 : ‘first’} {1 : ‘first’, ‘two’: 2, key:value} Keys must be of a hashable type (basically any type except mutables list, set or dict); Values can be any type. Dictionaries are unordered, so iterating over a dictionary provides key/value pairs in arbitrary order. To illustrate, the following examples all return a dictionary equal to {“one”: 1, “two”: 2, “three”: 3}:

a = dict(one=1, two=2, three=3)
b = {'one': 1, 'two': 2, 'three': 3}
c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
d = dict([('two', 2), ('one', 1), ('three', 3)])
e = dict({'three': 3, 'one': 1, 'two': 2})
a == b == c == d == e  #True

Iteration on Mappings/Dicts
If you iterate over a dictionary, it will give you its keys.
Dictionaries are best thought of as a container of keys, where each key also has a value associated with it. If you want, you can choose to use methods on the dictionary to iterate over its values, or over its key/value pairs as follows:

d = {'one': 1, 'two': 2, 'three': 3}
for k in d:
    print k
# prints: three, two, one
# Alternative to iterating over a dict:
for v in d.itervalues():
    print v
for k,v in d.iteritems():
    print k,v

Operators on Mappings/Dicts

len(d)         # The number of item s in d
dict()         # Creates an empty dictionary
dict(iterable) # Creates a dictionary init with (key , value) pairs provided by iterable.
dict(d)        # Creates a dictionary which is a copy of dictionary d.
d[k]           # The item of d with key k
d[k] = x       # Set value d[k] to x
del d[k]       # Removes d[k] from d
d.has_key(k), or
k in d         # True if d has key k, else False
d.items()      # A copy of d's list of (key , item ) pairs
d.keys()       # A copy of d's list of keys
d1.update(d2)  # for k, v in d2.items(): d1[k] = v
d.values()     # A copy of d's list of values
d.iteritems()  # Returns an iterator over (key , value) pairs.
d.iterkeys()   # Returns an iterator over the mapping's keys.
d.itervalues() # Returns an iterator over the mapping's values.
d.pop(k)       # Removes key k and returns the corresponding value.
d.get(k,0)     # Return  value for key k, or returns 0 if key k is not available.

Dictionary Views Since dicts states may change over time, python employs a dictionary view that reflects those changes dynamically. Here is an example of dictionary view usage:

dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
dkeys = dishes.viewkeys()
dvalues = dishes.viewvalues()
 # keys and values are iterated over in the same order
list(dkeys)  # ['eggs', 'bacon', 'sausage', 'spam']
list(dvalues) # [2, 1, 1, 500]
# view objects are dynamic and reflect dict changes
del dishes['eggs']
del dishes['sausage']
list(dkeys) # ['spam', 'bacon']
list(dvalues) # [ 500, 1]
Advertisements

Discussion

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: