prev | Draft Version 590 (Thu Dec 1 09:18:34 2005) | next |
[address, countSoFar]
list.sort
import sys def countFind(counts, address): for x in counts: if x[0] == address: return x return None def countFreq(lines): counts = [] for line in lines: line = line.strip() existing = countFind(counts, line) if existing: existing[1] += 1 else: counts.append([line, 1]) return counts def compareByFrequency(a, b): if a[1] < b[1]: return 1 if a[1] == b[1]: return 0 return -1 if __name__ == '__main__': instream = open(sys.argv[1], 'r') lines = instream.readlines() instream.close() result = countFreq(lines) result.sort(compareByFrequency) for address, frequency in result: print frequency, ":", address
%
operator is used to format strings'here %s go' % 'we'
creates a new string "here we go"
"%s"
in the left string means “insert a string here”'left %d right %d' % (-1, 1)
creates "left -1 right 1"
"%d"
stands for “decimal integer”'do %s %d times' % ('this', 99)
creates "do this 99 times"
'[%4d]' % 13
creates "[ 13]"
"%"
and "d"
specifies a width'[%-4d]' % 13
creates "[13 ]"
, because negative widths mean “left justify”'[%6.2f %%]' % 37.2
creates "[ 37.20 %]"
"%6.2f"
means “a floating point number, six characters wide, with two after the decimal point”"%%"
is translated into a single "%"
character"\\"
is how you represent a single "\"
in a string'[%6.2e %%]' % 37.2
creates "[3.72e+001 %]"
"%e"
is scientific (exponential) notationMercury | 87.97 |
Venus | 224.70 |
⋮ | ⋮ |
Pluto | 90550.0 |
{}
{'Newton':1642, 'Darwin':1809}
{}
[]
(just like everything else in Python)birthday = { 'Newton' : 1642, 'Darwin' : 1809 } print "Darwin's birthday:", birthday['Darwin'] print "Newton's birthday:", birthday['Newton']
Darwin's birthday: 1809 Newton's birthday: 1642
birthday = {} birthday['Darwin'] = 1809 birthday['Newton'] = 1942 # oops birthday['Newton'] = 1642 print birthday
{'Darwin': 1809, 'Newton': 1642}
birthday = { 'Newton' : 1642, 'Darwin' : 1809 } print birthday['Turing']
Traceback (most recent call last): File "key_error.py", line 5, in ? print birthday['Turing'] KeyError: 'Turing'
del d[k]
birthday = { 'Newton' : 1642, 'Darwin' : 1809, 'Turing' : 1912 } print 'Before deleting Turing:', birthday del birthday['Turing'] print 'After deleting Turing:', birthday
Before deleting Turing: {'Turing': 1912, 'Newton': 1642, 'Darwin': 1809} After deleting Turing: {'Newton': 1642, 'Darwin': 1809}
for k in d
loops over the dictionary's keys (rather than its values)
for
loops over the values, rather than the “keys” (indices)birthday = { 'Newton' : 1642, 'Darwin' : 1809, 'Turing' : 1912 } for name in birthday: print name, birthday[name]
Turing 1912 Newton 1642 Darwin 1809
k
is in a dictionary d
using k in d
birthday = { 'Newton' : 1642, 'Darwin' : 1809 } for name in ['Newton', 'Turing']: if name in birthday: print name, birthday[name] else: print 'Who is', name, '?'
Newton 1642 Who is Turing ?
Method | Purpose | Example | Result |
---|---|---|---|
clear | Empty the dictionary. | d.clear() | Returns None , but d is now empty. |
get | Return the value associated with a key, or a default value if the key is not present. | d.get('x', 99) | Returns d['x'] if "x" is in d , or 99 if it is not. |
keys | Return the dictionary's keys as a list. Entries are guaranteed to be unique. | birthday.keys() | ['Turing', 'Newton', 'Darwin'] |
items | Return a list of (key, value) pairs. | birthday.items() | [('Turing', 1912), ('Newton', 1642), ('Darwin', 1809)] |
values | Return the dictionary's values as a list. Entries may or may not be unique. | birthday.values() | [1912, 1642, 1809] |
update | Copy keys and values from one dictionary into another. | See the example below. |
birthday = { 'Newton' : 1642, 'Darwin' : 1809, 'Turing' : 1912 } print 'keys:', birthday.keys() print 'values:', birthday.values() print 'items:', birthday.items() print 'get:', birthday.get('Curie', 1867) temp = { 'Curie' : 1867, 'Hopper' : 1906, 'Franklin' : 1920 } birthday.update(temp) print 'after update:', birthday birthday.clear() print 'after clear:', birthday
keys: ['Turing', 'Newton', 'Darwin'] values: [1912, 1642, 1809] items: [('Turing', 1912), ('Newton', 1642), ('Darwin', 1809)] get: 1867 after update: {'Curie': 1867, 'Darwin': 1809, 'Franklin': 1920, 'Turing': 1912, 'Newton': 1642, 'Hopper': 1906} after clear: {}
# Data to count. names = ['Be','Mg','Mg','Ca','Be','Mg', 'Be'] # Build a dictionary of frequencies. freq = {} for name in names: # Already seen, so increment count by one. if name in freq: freq[name] = freq[name] + 1 # Never seen before, so add to dictionary. else: freq[name] = 1 # Display. print freq
{'Be': 3, 'Mg': 3, 'Ca': 1}
# Build the frequency dictionary as before. names = ['Be','Mg','Mg','Ca','Be','Mg', 'Be'] freq = {} for name in names: if name in freq: freq[name] = freq[name] + 1 else: freq[name] = 1 # Print in alphabetical order by key. keys = freq.keys() keys.sort() for k in keys: print k, freq[k]
Be 3 Ca 1 Mg 3
dict.get
# Use 'get' to simplify the counting loop. names = ['Be','Mg','Mg','Ca','Be','Mg', 'Be'] freq = {} for name in names: freq[name] = freq.get(name, 0) + 1 # Print. keys = freq.keys() keys.sort() for k in keys: print k, freq[k]
Be 3 Ca 1 Mg 3
{'a':1, 'b':1, 'c':1}
?# Count values as before. names = ['Be','Mg','Mg','Ca','Be','Mg', 'Be'] freq = {} for name in names: freq[name] = freq.get(name, 0) + 1 # Invert. inverse = {} for (key, value) in freq.items(): seen = inverse.get(value, []) seen.append(key) inverse[value] = seen # Print. keys = inverse.keys() keys.sort() for k in keys: print k, inverse[k]
1 ['Ca'] 3 ['Be', 'Mg']
"%"
can take a dictionary as its right argument"%(varname)s"
or "%(varname)4d"
inside format string to identify what's to be substituted'%(word)s, t%(word)s, and everyw%(word)s' % {'word' : 'here'}
creates "here, there, and everywhere"
if
/else
try
except
try
block, Python raises an exceptionexcept
block, and executes whatever instructions it containsprint 'before try/except' try: print '..first line of try block' print 1/0 print '..last line of try block' except: print '..handling error!' print 'after try/except'
before try/except ..first line of try block ..handling error! after try/except
else
for val in (0.0, 1.0): print "val is", val try: x = 1.0/val except: print '..handling error!' else: print '...in the else block'
val is 0.0 ..handling error! val is 1.0 ...in the else block
except
statementexcept ExceptionType, variable
ExceptionType
is what you want to catchvariable
values = [-1.0, 0.0, 1.0] for i in range(4): # note: top index will be out of bounds try: x = 1.0 / values[i] except ZeroDivisionError, e: print 'divide by zero:', e
divide by zero: float division
Traceback (most recent call last): File "except_with_type.py", line 4, in ? x = 1.0 / values[i] IndexError: list index out of range
except
blocks with a single try
except
appears, it must be the last one (since it catches everything)
except Exception, e
so that you have the exception objectZeroDivisionError
, OverflowError
, and FloatingPointError
are all specialized versions of ArithmeticError
IndexError
(list/string index out of bounds) and KeyError
(non-existent dictionary key) are specializations of LookupError
for i in range(2): try: if i == 0: vals = ['a', 'b'] x = vals[99] else: vals = {20 : 'a', 30 : 'b'} x = vals[40] except KeyError, e: print 'loop %d, handling key errors:' % i, e except LookupError, e: print 'loop %d, handling generic lookup errors:' % i, e
loop 0, handling generic lookup errors: list index out of range loop 1, handling key errors: 40
Name | Purpose |
---|---|
Exception | Root of exception hierarchy. |
ArithmeticError | Illegal arithmetic operation |
IndexError | Bad index to sequence (out of bounds or illegal type) |
KeyError | Nonexistent index to dictionary |
TypeError | Illegal type (e.g., trying to add integer and string) |
ValueError | Illegal value (e.g., math.sqrt(-1) ) |
IOError | Unable to create or open file, read data, etc. |
try
/except
block, it pushes the except
handlers on a stackdef invert(vals, index): try: vals[index] = 1/vals[index] except ArithmeticError, e: print 'inner exception handler:', e def each(func, vals, indices): try: for i in indices: func(vals, i) except IndexError, e: print 'outer exception handler:', e # Note: top index will be out of bounds allValues = [-1, 0, 1] allIndices = [0, 1, 2, 3] each(invert, allValues, allIndices)
calling func for index 0 calling func for index 1 inner exception handler: integer division or modulo by zero calling func for index 2 calling func for index 3 outer exception handler: list index out of range
raise
to trigger exception processingraise Exception('this is an error message')
for i in range(4): try: # Raise exception if value is odd. if (i % 2) == 1: raise ValueError('index is odd') else: print 'not raising exception for %d' % i except ValueError, e: print 'caught exception for %d' % i, e
not raising exception for 0 caught exception for 1 index is odd not raising exception for 2 caught exception for 3 index is odd
None
or -1 or something like thatlist.find
(which returns -1 if something can't be found) is unusual in this respectlist.index
, which throws an exceptionstderr
import sys # Look for the first matching line in a file. def findFirstMatchingLine(filename, word): infile = open(filename, 'r') lines = infile.readlines() infile.close() for line in lines: if line.find(word) >= 0: return line.rstrip() errMsg = '%s does not contain %s' % (filename, word) raise ValueError(errMsg) if __name__ == '__main__': try: word = sys.argv[1] for filename in sys.argv[2:]: line = findFirstMatchingLine(filename, word) print '%s / %s => %s' % (filename, word, line) except ValueError, e: print >> sys.stderr, e except IOError, e: print >> sys.stderr, e except Exception, e: print >> sys.stderr, e
import sys # Look for the first matching line in a file. def findFirstMatchingLine(filename, word): infile = open(filename, 'r') lines = infile.readlines() infile.close() for line in lines: if line.find(word) >= 0: return line.rstrip() errMsg = '%s does not contain %s' % (filename, word) raise ValueError(errMsg) if __name__ == '__main__': try: word = sys.argv[1] for filename in sys.argv[2:]: line = findFirstMatchingLine(filename, word) print '%s / %s => %s' % (filename, word, line) except ValueError, e: print >> sys.stderr, e except IOError, e: print >> sys.stderr, e except Exception, e: print >> sys.stderr, e
math.sqrt
string.find
assert
statementAssertionError
exceptiondef findRange(values): assert (values != None) and (len(values) > 0), 'Illegal input' left = min(values) right = max(values) assert left < right, 'Empty range' return (left, right)
assert
to check that your program managed to open a fileos.popen
runs a command, and lets you either:
ls
command into your programimport os instream = os.popen('ls', 'r') lines = instream.readlines() instream.close() for line in lines[:4]: line = line.rstrip() print '%4d: %s' % (len(line), line)
13: addresses.txt 13: assertions.py 14: create_dict.py 18: create_dict.py.out
gzip
for compression:
import os # Create compressed output and report its size. outstream = os.popen('gzip -c > temp.txt.gz', 'w') for i in range(1000): for word in 'this is a test'.split(): print >> outstream, word outstream.close() print 'output is %d bytes' % os.stat('temp.txt.gz').st_size # See how big it would have been. instream = os.popen('gunzip -c temp.txt.gz', 'r') total = 0 for line in instream.readlines(): total += len(line) instream.close() print 'output would have been %d bytes' % total
output is 79 bytes output would have been 15000 bytes
os.popen2
to connect to the other program's input and output simultaneouslyimport os childIn, childOut = os.popen2('sort') for word in 'this is a test'.split(): print >> childIn, word childIn.close() for line in childOut.readlines(): print line.rstrip() childOut.close()
a is test this
os.popen3
, which gives you the child process's stdin
, stdout
, and stderr
stdout
while it's trying to write an error message to stderr
, both programs will be blockedos.popen
(with temporary files if necessary) until you're comfortable enough to move onExercise 10.1:
Suppose you wanted to sort entries with the same frequency
alphabetically. What changes would you have to make to
compareByFrequency
?
prev | Copyright © 2005, Python Software Foundation. See License for details. | next |