| prev | Draft Version 590 (Wed Nov 9 17:41:14 2005) | next |
[address, countSoFar]list.sortimport 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) notation| Mercury | 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
tryexcepttry 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 catchvariablevalues = [-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 ArithmeticErrorIndexError (list/string index out of bounds) and KeyError (non-existent dictionary key) are specializations of LookupErrorfor 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 exceptionstderrimport 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.sqrtstring.findassert 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 |