python 的超级模块
fileinput 这个模块让你能够轻松的遍历文本文件的所有行
fileinput.filename 函数返回当前正在处理的文件名
fileinput.lineno 返回当前行的行数
fileinput.filelineno 返回当前处理文件文件的当前行数
#代码例子 为Python脚本添加行号
import fileinput #便于遍历多个输入流中的行
for line in fileinput.input(inplace=True): #fileinput.input他能够用于for循环遍历的对象
line = line.rstrip() #Python rstrip() 删除 string 字符串末尾的指定字符(默认为空格).
num = fileinput.lineno() #fileinput.lineno() 返回当前行的行数
print '%-40s # %2i' % (line,num)
#运行python ljl.py ljl.py 则会给ljl.py这个文件自动添加行号
#集合、堆和双端队列
print set(range(10)) #集合是由列表(或者其他可迭代对象)构建的
print set(['lijial','ljl','ljj'])
a = set([1,2,3])
b = set([2,3,4])
print a.union(b)
print a | b
c = a & b
print "c=",c
print c.issubset(a) # 测试是否 c 中的每一个元素都在 a 中
print c.issuperset(a) # 测试是否 a 中的每一个元素都在 c 中
print a.intersection(b) #返回一个新的 set 包含 a 和 b 中的公共元素
print a.difference(b) #返回一个新的 set 包含 a 中有但是 b 中没有的元素
print a - b
print a.symmetric_difference(b) # 返回一个新的 set 包含 a 和 b 中不重复的元素
print a.copy()
print a.copy() is a
#需要一个函数,用于查找并且打印两个集合的并集,可以使用来自set类型的union方法来绑定版本
mySets = []
for i in range(10):
mySets.append(set(range(i,i+5)))
print reduce(set.union,mySets)
堆
#heappush函数用于增加堆的顶。注意,不能将它用于任何之前讲述的列表中--他只能用于通过各种堆函数建立的列表中。
from heapq import *
from random import shuffle
data = range(10)
shuffle(data) #shuffle() 方法将序列的所有元素随机排序。
heap = []
for n in data:
heappush(heap,n) #将x入栈
print heap
heappush(heap,0.5)
print heap
print heappop(heap) #heappop函数弹出最小元素--一般来说都是在索引0处的元素,并且会切薄剩余元素中最小的那个元素战就这个位置
print heappop(heap)
print heappop(heap)
print heap
heap = [5,8,0,3,6,7,9,1,4,2]
heapify(heap) #heapify函数使用人以列表作为参数,并且通过尽可能少的移位操作,将其转换为合法的堆。
print heap
print heapreplace(heap,0.5) #heapreplace函数不像其他函数那么常用,他弹出堆得最小元素,并将新元素推入。
#双端列表
from collections import deque
q = deque(range(5))
q.append(5)
q.appendleft(6)
print q
print q.pop()
print q.popleft()
q.rotate(3) #旋转队列,默认时值为1,由右边开始旋转,负值代表左边旋转,n代表从队列的第n个元素开始,n从1开始计数
print q
q.rotate(-1)
print q
#time模块 它所包含的函数能实现以下功能:获取当前时间、操作时间和日期、从字符串读取时间以及格式化时间为字符串
#mkdir 该函数可以讲这样的元组转换为时间戳,而时间戳从新纪元开始以秒来量
import time
print time.asctime() #asctime将时间元祖转换为字符串
print type(time.asctime())
time.sleep(1) #让解释器等待给定的秒数
print time.localtime() #将秒数转换为日期元祖,以本地时间为准,如果想获得全球统一时间,则可以使用gmtime
#print time.mktime() #将时间元祖转换为本地时间
#print time.strptime() #将asctime格式化过的字符串转换为日期数组
print time.time() #使用自新纪元开始计算的秒数返回当前(全球统一)时间
random模块 返回0<n<1之间的随机实数n
#getrandbits(n) 以长整数形式返回n个随机位
#举个栗子 首先获得代表时间间隔(2008年)限制的实数,这可以通过实践元祖的方式来表示日期(使用-1表示一周中的某一天
#、一年中的某天和夏令时,以便让Python自己计算 ,并且对这些远足调用mktime)
from random import *
from time import *
date1 = (2008,1,1,0,0,0,-1,-1,-1)
time1 = mktime(date1)
date2 = (2009,1,1,0,0,0,-1,-1,-1)
time2 = mktime(date2) #mktime(tuple) 将时间元祖转换为本地时间
#然后就能在这个范围内均一的生成随机数:
random_time = uniform(time1,time2) #uniform(a,b) 返回随机实数n,其中a<=n<b
#然后,可以将数字转换为易读的日期形式:
print asctime(localtime(random_time)) #localtime([secs]) 将秒数转换为日期元祖,以本地时间为准
#asctime([tuple]) 将时间元祖转换为字符串
第二个random栗子
#我们要求用户选择投掷的筛子数以及每个筛子具有的面数。筛子投掷机制可以由randrange和for循环实现
from random import randrange #randrange([start],stop,[step]) 返回range(start,stop,step)中的随机数
num = input('How many dice?')
sides = input('How many sides per die?')
sum = 0
for i in range(num):
sum += randrange(sides) + 1
print 'The result is',sum
最后一个栗子,首先你希望程序能够在每次敲击回车的时候为自己发一张牌,同时还要确保不会获得相同的牌。首先要创建“一副牌”---字符串列表
values = range(1,11) + 'Jack Queen King'.split()
suits = 'diamonds clubs hearts spades'.split()
deck = ['%s of %s' % (v,s) for v in values for s in suits]
from pprint import pprint
'''
pprint 包含一个“美观打印机”,用于生成数据结构的一个美观视图。格式化工具会生成数据结构的一些表示,
不仅可以由解释器正确地解析,而且便于人类阅读。输出尽可能放在一行上,分解为多行时则需要缩进。
'''
pprint(deck[:12])
from random import shuffle
shuffle(deck) #shuffle主要是将一个列表里面的顺序打乱
pprint(deck[:12])
"""
最后为了让Python在每次会车的时候都给你发一张牌,知道发完为止,那么只需要创建一个小的while
循环即可。假设将建立牌的代码放在程序文件中,那么只需要在程序的结尾处加入下面这行代码即可
"""
while deck:
raw_input(deck.pop())
#shelve 如果你需要一个简单的存储方案,那么shelve模块可以满足你的大部分需求,你所做的就只是为他提供文件名
1.潜在的意识,意识到shelve.open函数返回的对象并不是普通的映射还是很重要的,如下面的例子
import shelve
"""
当你在shelf对象中查找元素的时候,这和对象就会更具已经存储的版本进行重新构建
当你将元素复制给某个键的时候,他就被存储了
"""
s = shelve.open('test1.txt')
s['x'] = ['a','b','c'] #列表['a',b','c']存储在键x下
s['x'].append('d') #获得存储的表示,并且根据它来创建新的列表,而'd'被添加到这个副本中。修改的版本还没有被保存
print s #最终获得原始版本---没有d
"""
为了正确使用地使用shelve模块存储的对象,必须将临时变量绑定到获得的版本上,并且在他被修改后重新存储这个副本
"""
temp = s['x']
temp.append('d')
s['x'] = temp
print s['x']
2.简单的数据库示例
import sys,shelve
def store_person(db):
"""
query user for dara and store it in the shelf object
:param db:
:return:
@guohang
"""
pid = raw_input('Enter unique ID number:')
person = {}
person['name'] = raw_input('Enter name:')
person['age'] = raw_input('Enter age:')
person['phone'] = raw_input('Enter phone number:')
db[pid] = person
def lookup_person(db):
"""
query user for ID and desired filed.and fetch the corresponding data from
the shelf object
:param db:
:return:
@guohang
"""
pid = raw_input('Enter ID number:')
field = raw_input('What would you like to konw?(name,age,phone)')
field = field.strip().lower()
print field.capitalize() + ':' + db[pid][field] #capitalize()将字符串的第一个字母变成大写,其他字母变小写。对于 8 位字节编码需要根据本地环境。
def print_help():
"""
:return:
"""
print 'The avaliable commands are:'
print 'store :Stores infomation about a person'
print 'lookup :Looks up a person from ID number'
print 'quit :Save changes and exit'
print '? :Prints this message'
def enter_command():
cmd = raw_input('Enter command (? for help):')
cmd = cmd.strip().lower()
return cmd
def main():
"""
:return:
"""
database = shelve.open('E:\\database.bat') #You may want to change this name
try:
while True:
cmd = enter_command()
if cmd == 'store':
store_person(database)
elif cmd == 'lookup':
lookup_person(database)
elif cmd == '?':
print_help()
elif cmd == 'quit':
return
finally:
database.close()
if __name__ == '__main__':
main()
re 这个模块包含正则表达式
函数re.compile将正则表达式转换为模式对象,可以实现更有效率的匹配
如果在调用search过着match函数的时候使用字符串表示正则表达式,他们会在内部将字符串转换为正则表达式对象。
import re
some_text = 'alpha. beta....gamma delta'
print re.split('[. ] +',some_text)
print re.split('[. ]+', some_text,maxsplit=2) #maxsplit参数表示字符串最多可以分割成地部分数
print re.split('[. ]+', some_text,maxsplit=1)
pat = '[a-zA-Z]+'
text = '"Hm...Err -- are you sure?" he said,sounding insecure.'
print re.findall(pat,text) #函数re.findall以列表的形式返回给定模式的所有匹配项
pat1 = r'[.?\-",]+'
print re.findall(pat1,text)
re.sub的作用在于:使用给定的替换内容将匹配模式的子字符串(最左端并非重叠的子字符串)替换掉
pat = '{name}'
text ='Dear {name}...'
print re.sub(pat,'Mr.Gumby',text) #sub(pat,repl,string[. count=0]) 字符串中所有的pat的匹配项用repl换掉
#re.escape是一个很实用的函数,他可以对字符串中所有可能被解释为正则运算符的字符进行转移的应用函数
print re.escape('www.python.org')
print re.escape('But where is the ambiguity?')
匹配对象和组 简而言之 组就是放置在元括号内的子模式。组的序号取决于他左侧的括号数
m = re.match(r'www\.(.*)\..{3}','www.python.org')
print m.group(1) #获取给定子模式的匹配项
print m.start(1) #返回给定组的匹配项的开始位置
print m.end(1) #返回给定组的匹配项的结束位置
print m.span(1) #返回一个组的开始和结束位置
让正则表达式变得更加容易读懂的方式是在re函数中使用VERBOSE标志,它允许在模式中添加空白(空白字符、tab、换行符,等等)
,re则会忽略他们--除非将其放在字符类或者用反斜线转义。
emphasis_pattern = re.compile(r'''
\* #beginning emphasis tag -- an asterisk
( #begininig group for capturing phrase
[^\*]+ #capture anything except asterisks
) #End group
\* #Ending emphasis tag
''',re.VERBOSE)
m = re.match(emphasis_pattern,'Hello,*world*!')
print m.group(1)
print re.sub(emphasis_pattern,r'<em>\1<\em>','Hello,*world*!')
寻找Email发信人的程序
import fileinput,re
pat = re.compile('From:(.*) <.*?>$')
for line in fileinput.input():
m = pat.match(line)
if m:print m.group(1)
pat1 = re.compile(r'[a-z\-\.]+@[a-z\-\.]+'.re.IGNORECASE)
6.模板系统示例
加入需要把所有的'[somethings]'(字段)的匹配项替换成通过Python表达式计算出来的something结果,所以下面的字符串
#一个模板系统
import fileinput,re
#匹配中括号里的字段:
field_pat = re.compile(r'[(.+?)\]')
#我们将变量收集到这里:
scope = {}
#用于re.sub中:
def replacement(match):
code = match.group(1)
try:
#如果字段可以求值,返回它:
return str(evl(code,scope)) #Python中的eval函数可以计算Python表达式,并返回结果
except SyntaxError:
#否则执行相同作用域的赋值语句......
exec code in scope
#... ...返回空字符串:
return ''
#将所有文本以一个字符串的形式获取
#(还有其他的方法)
lines = []
for line in fileinput.input():
lines.append(line)
text = ''.join(lines)
#将field模式的所有匹配项都替换掉:
print field_pat.sub(replacement,text)