Please send questions to st10@humboldt.edu .
Python 2.5 (r25:51918, Sep 19 2006, 08:49:13) 
[GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin
Type "copyright", "credits" or "license()" for more information.

IDLE 1.2      

>>> # tuple - a simple sequence type, an ordered collection
>>> #    that is IMMUTABLE

>>> # the most popular way to write a tuple: a comma-separated
>>> #    list of objects surrounded by parentheses

>>> t = ()
>>> type(t)
<type 'tuple'>

>>> t = (1, 2, 3)
>>> type(t)
<type 'tuple'>

>>> # I can index a tuple like I index a list...

>>> myTuple = (1, 2, 3, 4, 5, 6, 7)
>>> myTuple[0]
1

>>> # I can slice a tuple like I slice a list...

>>> myTuple[3:6]
(4, 5, 6)

>>> myTuple = ('Cleese', 'Palin', 13, 'spam', "Ni", 14.6, [1, 2, 3])
>>> myTuple[0]
'Cleese'

>>> myTuple[3:6]
('spam', 'Ni', 14.6)

>>> # but tuples are immutable...(cannot CHANGE their contents)

>>> myTuple[3] = "Monty Python"

Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    myTuple[3] = "Monty Python"
TypeError: 'tuple' object does not support item assignment

>>> myTuple.append(15)

Traceback (most recent call last):
  File "<pyshell#20>", line 1, in <module>
    myTuple.append(15)
AttributeError: 'tuple' object has no attribute 'append'

>>> # tuples cannot use list methods...
>>> # BUT, tuples CAN use:
>>> #    len

>>> len(myTuple)
7

>>> #    concatenation

>>> myTuple + t
('Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3], 1, 2, 3)

>>> #   * for repetition

>>> myTuple * 8
('Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3], 'Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3], 'Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3], 'Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3], 'Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3], 'Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3], 'Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3], 'Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3])

>>> #   in for membership (to see if something is in the tuple)

>>> myTuple
('Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3])

>>> 'Cleese' in myTuple
True

>>> 'Jonathan' in myTuple
False

>>> #    for..in to walk through a tuple

>>> for item in myTuple:
	print item

	
Cleese
Palin
13
spam
Ni
14.6
[1, 2, 3]

>>> # how do you write a one-item tuple?
>>> # to avoid a "syntax collision", a one-item tuple
>>> #    needs to be written with a COMMA following the 1 item

>>> type( (40) )
<type 'int'>

>>> type( (40,) )
<type 'tuple'>

>>> # there are times that you can omit the parentheses around
>>> #    tuples - BUT I think it is easier and more readable to
>>> #    just put 'em.
>>> # Look at www.python.org to find out more about this if you
>>> #    are interested.

>>> # you can get a list with a tuple's elements with the list
>>> #    function...

>>> list(myTuple)
['Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3]]

>>> # you can get a tuple with a list's elements with the
>>> #    tuple function

>>> tuple([1, 'a', 'beep'])
(1, 'a', 'beep')

>>> # but with strings, both of these return collections of
>>> #    characters

>>> tuple('Cleese')
('C', 'l', 'e', 'e', 's', 'e')

>>> list('Cleese')
['C', 'l', 'e', 'e', 's', 'e']

>>> # why would one ever use a tuple instead of a list?
>>> # maybe you want a sequenced collection that is guaranteed
>>> #    not to change;
>>> # maybe you want to use a sequenced collection in a place
>>> #    where a mutable object is not allowed...
>>> # like in....

>>> # a DICTIONARY!!

>>> # ...an unordered collection;
>>> # ...has items stored and fetched by KEY, instead of by
>>> #   positional offset;
>>> # some call this an associative list;
>>> # in Perl, these are called hashes (I think)

>>> # dictionaries are implemented in Python using hash tables

>>> # grabbing an element from a dictionary based on its key
>>> #    is a very fast operation;

>>> # dictionaries are still variable length,
>>> #    can grow and shrink (they are mutable)

>>> # you write a dictionary literal as curly braces around
>>> #    key-value pairs that are val1:val2 separated by commas

>>> # an empty dictionary

>>> myDict = {}

>>> myDict
{}

>>> type(myDict)
<type 'dict'>

>>> len(myDict)
0

>>> # a non-empty dictionary:

>>> myDict = {'spam':2, 3:'eggs'}

>>> # the length of a dictionary is the number of key-value pairs;
>>> # in myDict, the length is two,
>>> #    key 'spam' has value 2, and
>>> #    key 3 has value 'eggs'

>>> len(myDict)
2

>>> # I can grab the value for a key by writing the key in
>>> #    square brackets after the dictionary's name;

>>> myDict['spam']
2

>>> myDict[3]
'eggs'

>>> myDict
{3: 'eggs', 'spam': 2}

>>> # thou SHALT access dictionary values by KEY only -
>>> #    no positional offsets allowed!
>>> # (it will just think that index is a key, and treat it accordingly...!)

>>> myDict[0]

Traceback (most recent call last):
  File "<pyshell#102>", line 1, in <module>
    myDict[0]
KeyError: 0

>>> # a dictionary *value* can be just about any object;
>>> # BUT: a dictionary KEY must be immutable.

>>> aDict = {13.7:'a', 3:'spam', (1, 2, 4):'ha', 5:{'a':4, 'b':5,
						'c':{'x':1, 'y':2}}}

>>> aDict
{13.699999999999999: 'a', 3: 'spam', 5: {'a': 4, 'c': {'y': 2, 'x': 1}, 'b': 5}, (1, 2, 4): 'ha'}

>>> len(aDict)
4

>>> aDict[13.7]
'a'

>>> aDict[13.699999999999999]
'a'

>>> aDict[13.69]

Traceback (most recent call last):
  File "<pyshell#119>", line 1, in <module>
    aDict[13.69]
KeyError: 13.69

>>> aDict[5]
{'a': 4, 'c': {'y': 2, 'x': 1}, 'b': 5}

>>> aDict[5]['c']
{'y': 2, 'x': 1}

>>> aDict[5]['c']['x']
1

>>> # to add a new key-value pair - write a dictionary value
>>> #    reference and set it equal to the new value for that
>>> #    key

>>> myTuple
('Cleese', 'Palin', 13, 'spam', 'Ni', 14.6, [1, 2, 3])

>>> myDict
{3: 'eggs', 'spam': 2}

>>> myDict['sausage'] = 27
>>> myDict
{'sausage': 27, 3: 'eggs', 'spam': 2}

>>> myDict['ham'] = 27
>>> myDict
{'sausage': 27, 3: 'eggs', 'ham': 27, 'spam': 2}

>>> myDict['sausage'] = 'guilt'
>>> myDict
{'sausage': 'guilt', 3: 'eggs', 'ham': 27, 'spam': 2}

>>> # how can you politely see if a key is in a dictionary?

>>> # has_key method returns True if the key argument is in the
>>> #    calling dictionary, and False otherwise...

>>> myDict.has_key('sausage')
True

>>> myDict.has_key('links')
False

>>> # or, you can use the in operator - for a dictionary,
>>> #    it tells you if the value is a KEY in that dictionary;

>>> 'sausage' in myDict
True

>>> 'links' in myDict
False

>>> myDict
{'sausage': 'guilt', 3: 'eggs', 'ham': 27, 'spam': 2}

>>> 'guilt' in myDict
False

>>> # the keys method returns a list of the keys in a dictionary

>>> myDict.keys()
['sausage', 3, 'ham', 'spam']

>>> keyList = myDict.keys()
>>> keyList
['sausage', 3, 'ham', 'spam']

>>> keyList.sort()

>>> keyList
[3, 'ham', 'sausage', 'spam']

>>> # ...so if you want key values printed in an order based
>>> #    on the sorted keys...

>>> # (but NOTE that for..in loop uses RETURNED value ---
>>> #    so method calls that don't return anything don't work...)

>>> for myKey in myDict.keys().sort():
	print str(myKey), ":", str(myDict[myKey])

	

Traceback (most recent call last):
  File "<pyshell#157>", line 1, in <module>
    for myKey in myDict.keys().sort():
TypeError: 'NoneType' object is not iterable

#   (this will work, though, to loop through the sorted keys)

>>> keyList = myDict.keys()
>>> keyList.sort()
>>> for myKey in keyList:
	print str(myKey), ":", str(myDict[myKey])

	
3 : eggs
ham : 27
sausage : guilt
spam : 2

>>> # values method returns a list of the values within a
>>> #    dictionary...

>>> myDict.values()
['guilt', 'eggs', 27, 2]

>>> aDict.values()
['a', 'spam', {'a': 4, 'c': {'y': 2, 'x': 1}, 'b': 5}, 'ha']

>>> myDict[(1, 2, 3)] = 2
>>> myDict
{'sausage': 'guilt', 3: 'eggs', 'ham': 27, (1, 2, 3): 2, 'spam': 2}

>>> # remember: a list cannot be a key (keys must be immutable)

>>> myDict[ [1, 2, 3] ] = 2

Traceback (most recent call last):
  File "<pyshell#169>", line 1, in <module>
    myDict[ [1, 2, 3] ] = 2
TypeError: list objects are unhashable

>>> myDict
{'sausage': 'guilt', 3: 'eggs', 'ham': 27, (1, 2, 3): 2, 'spam': 2}

>>> myDict.values()
['guilt', 'eggs', 27, 2, 2]

>>> # items method returns a list of key-value pairs as tuples!

>>> myDict.items()
[('sausage', 'guilt'), (3, 'eggs'), ('ham', 27), ((1, 2, 3), 2), ('spam', 2)]

>>> # can get a copy of a dictionary by using the copy method...

>>> d2 = myDict.copy()
>>> d2 == myDict
True
>>> d2 is myDict   # recall: is lets you see if two variables refer to
False              #    the SAME object in memory (the same memory location)

>>> d3 = myDict    # with =, d3 IS pointing to same object that myDict is!

>>> d3 is myDict
True

>>> # get method takes a key (or a key and a default value) as
>>> #    argument(s) ---
>>> # it returns the value for that key if the key is in the
>>> #    dictionary,
>>> # (1 arg version) it returns None if the key isn't there,
>>> # (2 arg version) it returns the given default if the key
>>> #    isn't there

>>> myDict
{'sausage': 'guilt', 3: 'eggs', 'ham': 27, (1, 2, 3): 2, 'spam': 2}

>>> myDict.get('spam')
2
>>> myDict.get('longhorn')
>>> myDict.get('longhorn', 0)
0

>>> # in answer to a question about aliasing - yes, if two variables
>>> #    refer to the same dictionary, changing the dictionary
>>> #    using one of those variables changes what the other
>>> #    variable "sees", too!

>>> d3['spam'] = 155
>>> myDict['spam']
155

>>> # does update method simply update a value for a key...?
>>> # NOOO! it kind of concatenates two dictionaries...
>>> # BUT beware - if the two dictionaries have the same key,
>>> #    that key appears once in the result (one of the key's
>>> #    values is lost)

>>> myDict
{'sausage': 'guilt', 3: 'eggs', 'ham': 27, (1, 2, 3): 2, 'spam': 2}

>>> aDict
{13.699999999999999: 'a', 3: 'spam', 5: {'a': 4, 'c': {'y': 2, 'x': 1}, 'b': 5}, (1, 2, 4): 'ha'}

>>> myDict.update(aDict)

>>> myDict
{'sausage': 'guilt', 3: 'spam', 'ham': 27, 'spam': 155, (1, 2, 3): 2, (1, 2, 4): 'ha', 13.699999999999999: 'a', 5: {'a': 4, 'c': {'y': 2, 'x': 1}, 'b': 5}}

>>> newDict = {'sausage': 'hello', 'spam': 'goodbye'}

>>> myDict.update(newDict)

>>> myDict
{'sausage': 'hello', 3: 'spam', 'ham': 27, 'spam': 'goodbye', (1, 2, 3): 2, (1, 2, 4): 'ha', 13.699999999999999: 'a', 5: {'a': 4, 'c': {'y': 2, 'x': 1}, 'b': 5}}

>>> # NOTE that update CHANGES the calling dictionary (returns
>>> #    nothing)

>>> # to REMOVE a key from a dictionary:
>>> # del dict_name[key]

>>> newDict
{'sausage': 'hello', 'spam': 'goodbye'}

>>> del newDict['spam']

>>> newDict
{'sausage': 'hello'}

>>> # dictionary method iteritems lets you grab (one at a
>>> #    time, say for a for..in loop) a key and its value
>>> #    for each key-value pair in a dictionary;

>>> knights = {'galahad': 'the pure', 'robin': 'the brave'}

>>> for k, v in knights.iteritems():
	print k, v

	
galahad the pure
robin the brave

>>> # (by the way... list method enumerate lets you grab the
>>> #    index and the value (one at a time, say for a for..in
>>> #    loop) for each value in a list...)

>>> # OOPS - enumerate is a function, not a list method!
>>> for i, v in enumerate(listy):
	print str(i), str(v)

	
0 a
1 13
2 b
3 27
4 hike

>>>