python基础学习笔记(八)

来源:互联网 发布:手机c语言编程软件ios 编辑:程序博客网 时间:2024/06/07 08:31


模块

前面有简单介绍如何使用import从外部模块获取函数并且为自己的程序所用:

>>> import math>>> math.sin(0)  #sin为正弦函数0.0

 

模块是程序

任何python程序都可以作为模块导入。假设写如下程序,并且将它保存为以C:\python\hello.py

#hello.pyprint "hello,world!"

下面通过python解释器调用:

>>> import sys>>> sys.path.append('c:/python')>>> import hellohello,world!

再来一次:

>>> import hello>>> 

怎么这次没结果?因为导入模块并不意味着在导入进执行某些操作。它们主要用于定义,比如变量、函数和类等。此外,因为只需要定义这些东西一次,导入模块多次和导入一次的效果是一样的。

 

 

模块用于定义

1、在模块中定义函数

假设我们编写了一个类似代码的模块,将其保存为hello2.py 文件。

#hello2.pydef hello():    print "hello, world !"

保存后,可以像下面这样导入:

>>> import hello2

模块会被执行,这意味着hello函数在模块的作用被定义了。因此可以通过以下方式来访问函数:

>>> hello2.hello()

hello.world!

 

 

2、在模块中增加测试代码

模块用来定义函数、类和其他内容,有时候在模块中添加一些检查模块本身是否正常工作的测试代码是非常有用的。 

复制代码
#hello3.pydef hello():    print "hello.world!"def test():    hello()if __name__ == '__main__': test()
复制代码

f __name__ == '__nain__' 解释

python文件的后缀为.py .py文件可以用来直接运行,就像一个独立的小程序;也可以用来作为模块被其它程序调用。

__name__是模块的内置属性,如果等于'__main__' 侧表示直接被使用,那么将执行方法test()方法;如果是被调用则不执行 if 判断后面的test()方法。

执行结果:

复制代码
>>> import hello3   #表示hello3模块被调用,不执行test方法,所以没有输出>>> hello3.hello()   #表示程序执行,调用test方法hello.world!>>> hello3.hello()   #这里是不是可以反复调用test方法 hello.world!
复制代码

 

 

 

让模块可用

前面的例子中,我们改变了sys.path,其中包含了一个目录列表,解释器在该列表中查找模块。在理想情况下,一开始sys.path本身就应该包含正确的目录,有两方法可以做到这一点: 一是将模块放置在合适的位置,别外一种是告诉解释器去哪里查找需要的模块。

1、将模块放置在正确的位置

来看看python解释器会从哪里查找模块

复制代码
>>> import sys,pprint>>> pprint.pprint(sys.path)['', 'I:\\Python27\\Lib\\idlelib', 'C:\\Windows\\system32\\python27.zip', 'I:\\Python27\\DLLs', 'I:\\Python27\\lib', 'I:\\Python27\\lib\\plat-win', 'I:\\Python27\\lib\\lib-tk', 'I:\\Python27', 'I:\\Python27\\lib\\site-packages', 'c:/python']
复制代码

尽管这些目录下都可以被找到,但site-packages 目录是最佳选择。

 

 

2、告诉编译器去哪里找

以下情况是告诉编译器去哪儿找的原因:

  ** 不希望将自己的模块填满python解释器的目录

  ** 没有在python解释器目录中存储文件的权限

  ** 想将模块放到其它位置

编辑sys.path ,前面就已经使用了

>>> import sys>>> sys.path.append('c:/python')

但更优雅的做法是配置pythonpath环境变量,方法和配置java 环境变量类似。

 

 

文档

模块信息的自然来源是文档,除了通过python书籍或标准python文档来查看某个函数的含义,也可以通过下面方式: 

复制代码
>>> print range.__doc__range([start,] stop[, step]) -> list of integersReturn a list containing an arithmetic progression of integers.range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.When step is given, it specifies the increment (or decrement).For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!These are exactly the valid indices for a list of 4 elements.
复制代码

这样就获得了关于range函数的精确描述。

 

 

time 模块

time模块所包括的函数能够实现 以下功能:获得当前时间,操作时间和日期,从字符串读取时间以及格式化时间为字符串。

time模块中重要的函数

 

 time.asctime将当前时间格式化为字符串:

>>> time.asctime()'Thu May 16 00:00:08 2013'

 

 

 

random模块

random模块包括返回随机的函数,可以用于模拟或者用于任何产生随机输出的程序。

random模块中的一些重要函数:

 

 

下面介绍使用random模块的例子,还需要用到time模块中的函数。

例1:首先获得代表时间间隔(2013年)限制的实数,这可以通过时间元组的方式来表示日期(使用 -1表示一周的某天,一年中某天和夏令时,以例让python自己计算),并且对这些元组调用mktime 

复制代码
from random import *from time import *data1 = (2013 ,1,1,0,0,0,-1,-1,-1)time1 = mktime(data1)data2 = (2014 ,1,1,0,0,0,-1,-1,-1)time2 = mktime(data2)#然后在这个范围内生成随机数>>> random_time = uniform(time1,time2)# 可以将数字转换成易读的日期形式>>> print asctime(localtime(random_time))Fri Jan 18 18:23:16 2013
复制代码

 

例2:下面一个例子,假设三个人打牌,首先要保证54张牌没有重复的,第人发手里18张(斗地主就不能平均分配了)。

复制代码
>>> values = range(1,13) + 'dwang xwang'.split()  #定义13个数字与大小王>>> suits = 'hei hong mei fang '.split()           # 定义牌的四种类型(黑、红、梅、方)>>> deck = ['%s of %s' %(v ,s ) for v in values for s in suits]  #循环嵌套将其循环组合>>> from pprint import pprint   #调用pprint 模块>>> pprint (deck [:18])         #输出18张牌['1 of hei', '1 of hong', '1 of mei', '1 of fang', '2 of hei', '2 of hong', '2 of mei', '2 of fang', '3 of hei', '3 of hong', '3 of mei', '3 of fang', '4 of hei', '4 of hong', '4 of mei', '4 of fang', '5 of hei', '5 of hong']#显然上面的输出太整齐,调用随机函数,随机一点>>> from random import shuffle>>> shuffle(deck)>>> pprint(deck[:18])['5 of fang', '6 of hong', '5 of mei', 'dwang of fang', 'xwang of fang', '10 of hong', '7 of mei', '12 of hong', '6 of hei', '12 of hei', '7 of hei', '8 of hei', '4 of fang', 'dwang of hei', '11 of hei', '12 of fang', '5 of hei', '2 of hong']
复制代码

不过,依然是有问题的,大小王不应该分类型(黑、红、梅、方),显然上面的结果不够完美。


模块

前面有简单介绍如何使用import从外部模块获取函数并且为自己的程序所用:

>>> import math>>> math.sin(0)  #sin为正弦函数0.0

 

模块是程序

任何python程序都可以作为模块导入。假设写如下程序,并且将它保存为以C:\python\hello.py

#hello.pyprint "hello,world!"

下面通过python解释器调用:

>>> import sys>>> sys.path.append('c:/python')>>> import hellohello,world!

再来一次:

>>> import hello>>> 

怎么这次没结果?因为导入模块并不意味着在导入进执行某些操作。它们主要用于定义,比如变量、函数和类等。此外,因为只需要定义这些东西一次,导入模块多次和导入一次的效果是一样的。

 

 

模块用于定义

1、在模块中定义函数

假设我们编写了一个类似代码的模块,将其保存为hello2.py 文件。

#hello2.pydef hello():    print "hello, world !"

保存后,可以像下面这样导入:

>>> import hello2

模块会被执行,这意味着hello函数在模块的作用被定义了。因此可以通过以下方式来访问函数:

>>> hello2.hello()

hello.world!

 

 

2、在模块中增加测试代码

模块用来定义函数、类和其他内容,有时候在模块中添加一些检查模块本身是否正常工作的测试代码是非常有用的。 

复制代码
#hello3.pydef hello():    print "hello.world!"def test():    hello()if __name__ == '__main__': test()
复制代码

f __name__ == '__nain__' 解释

python文件的后缀为.py .py文件可以用来直接运行,就像一个独立的小程序;也可以用来作为模块被其它程序调用。

__name__是模块的内置属性,如果等于'__main__' 侧表示直接被使用,那么将执行方法test()方法;如果是被调用则不执行 if 判断后面的test()方法。

执行结果:

复制代码
>>> import hello3   #表示hello3模块被调用,不执行test方法,所以没有输出>>> hello3.hello()   #表示程序执行,调用test方法hello.world!>>> hello3.hello()   #这里是不是可以反复调用test方法 hello.world!
复制代码

 

 

 

让模块可用

前面的例子中,我们改变了sys.path,其中包含了一个目录列表,解释器在该列表中查找模块。在理想情况下,一开始sys.path本身就应该包含正确的目录,有两方法可以做到这一点: 一是将模块放置在合适的位置,别外一种是告诉解释器去哪里查找需要的模块。

1、将模块放置在正确的位置

来看看python解释器会从哪里查找模块

复制代码
>>> import sys,pprint>>> pprint.pprint(sys.path)['', 'I:\\Python27\\Lib\\idlelib', 'C:\\Windows\\system32\\python27.zip', 'I:\\Python27\\DLLs', 'I:\\Python27\\lib', 'I:\\Python27\\lib\\plat-win', 'I:\\Python27\\lib\\lib-tk', 'I:\\Python27', 'I:\\Python27\\lib\\site-packages', 'c:/python']
复制代码

尽管这些目录下都可以被找到,但site-packages 目录是最佳选择。

 

 

2、告诉编译器去哪里找

以下情况是告诉编译器去哪儿找的原因:

  ** 不希望将自己的模块填满python解释器的目录

  ** 没有在python解释器目录中存储文件的权限

  ** 想将模块放到其它位置

编辑sys.path ,前面就已经使用了

>>> import sys>>> sys.path.append('c:/python')

但更优雅的做法是配置pythonpath环境变量,方法和配置java 环境变量类似。

 

 

文档

模块信息的自然来源是文档,除了通过python书籍或标准python文档来查看某个函数的含义,也可以通过下面方式: 

复制代码
>>> print range.__doc__range([start,] stop[, step]) -> list of integersReturn a list containing an arithmetic progression of integers.range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.When step is given, it specifies the increment (or decrement).For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!These are exactly the valid indices for a list of 4 elements.
复制代码

这样就获得了关于range函数的精确描述。

 

 

time 模块

time模块所包括的函数能够实现 以下功能:获得当前时间,操作时间和日期,从字符串读取时间以及格式化时间为字符串。

time模块中重要的函数

 

 time.asctime将当前时间格式化为字符串:

>>> time.asctime()'Thu May 16 00:00:08 2013'

 

 

 

random模块

random模块包括返回随机的函数,可以用于模拟或者用于任何产生随机输出的程序。

random模块中的一些重要函数:

 

 

下面介绍使用random模块的例子,还需要用到time模块中的函数。

例1:首先获得代表时间间隔(2013年)限制的实数,这可以通过时间元组的方式来表示日期(使用 -1表示一周的某天,一年中某天和夏令时,以例让python自己计算),并且对这些元组调用mktime 

复制代码
from random import *from time import *data1 = (2013 ,1,1,0,0,0,-1,-1,-1)time1 = mktime(data1)data2 = (2014 ,1,1,0,0,0,-1,-1,-1)time2 = mktime(data2)#然后在这个范围内生成随机数>>> random_time = uniform(time1,time2)# 可以将数字转换成易读的日期形式>>> print asctime(localtime(random_time))Fri Jan 18 18:23:16 2013
复制代码

 

例2:下面一个例子,假设三个人打牌,首先要保证54张牌没有重复的,第人发手里18张(斗地主就不能平均分配了)。

复制代码
>>> values = range(1,13) + 'dwang xwang'.split()  #定义13个数字与大小王>>> suits = 'hei hong mei fang '.split()           # 定义牌的四种类型(黑、红、梅、方)>>> deck = ['%s of %s' %(v ,s ) for v in values for s in suits]  #循环嵌套将其循环组合>>> from pprint import pprint   #调用pprint 模块>>> pprint (deck [:18])         #输出18张牌['1 of hei', '1 of hong', '1 of mei', '1 of fang', '2 of hei', '2 of hong', '2 of mei', '2 of fang', '3 of hei', '3 of hong', '3 of mei', '3 of fang', '4 of hei', '4 of hong', '4 of mei', '4 of fang', '5 of hei', '5 of hong']#显然上面的输出太整齐,调用随机函数,随机一点>>> from random import shuffle>>> shuffle(deck)>>> pprint(deck[:18])['5 of fang', '6 of hong', '5 of mei', 'dwang of fang', 'xwang of fang', '10 of hong', '7 of mei', '12 of hong', '6 of hei', '12 of hei', '7 of hei', '8 of hei', '4 of fang', 'dwang of hei', '11 of hei', '12 of fang', '5 of hei', '2 of hong']
复制代码

不过,依然是有问题的,大小王不应该分类型(黑、红、梅、方),显然上面的结果不够完美。




re模块包含对 正则表达式。本章会对re模块主要特征和正则表达式进行介绍。

 

什么是正则表达式

正则表达式是可以匹配文本片段的模式。最简单的正则表达式就是普通字符串,可以匹配其自身。换包话说,正则表达式python 可以匹配字符串python 。你可以用这种匹配行为搜索文本中的模式,并且用计算后有值并发特定模式,或都将文本进行分段。

 

** 通配符

正则表达式可以匹配多于一个的字符串,你可以使用一些特殊字符创建这类模式。比如点号(.)可以匹配任何字符。在我们用window 搜索时用问号(?)匹配任意一位字符,作用是一样的。那么这类符号就叫 通配符。

 

** 对特殊字符进行转义

通过上面的方法,假如我们要匹配“python.org”,直接用用‘python.org’可以么?这么做可以,但这样也会匹配“pythonzorg”,这可不是所期望的结果。

好吧!我们需要对它进行转义,可以在它前面加上发斜线。因此,本例中可以使用“python\\.org”,这样就只会匹配“python.org”了。

 

** 字符集

我们可以使用中括号([ ])括住字符串来创建字符集。可以使用范围,比如‘[a-z]’能够匹配az的任意一个字符,还可以通过一个接一个的方式将范围联合起来使用,比如‘[a-zA-Z0-9]’能够匹配任意大小写字母和数字。

反转字符集,可以在开头使用^字符,比如‘[^abc]’可以匹配任何除了abc之外的字符。

 

** 选择符

有时候只想匹配字符串python 和 perl  ,可以使用选择项的特殊字符:管道符号(|) 。因此, 所需模式可以写成python|perl 。

 

** 子模式

但是,有些时候不需要对整个模式使用选择符---只是模式的一部分。这时可以使用圆括号起需要的部分,或称子模式。 前例可以写成 p(ython | erl)

 

** 可选项

在子模式后面加上问号,它就变成了可选项。它可能出现在匹配字符串,但并非必须的。

r(heep://)?(www\.)?python\.org

只能匹配下列字符:

http://www.python.org

http://python.org

www.python.org

python.org

 

** 重复子模式

(pattern)* : 允许模式重复0次或多次

(pattern)+ : 允许模式重复1次或多次

(pattern){m,n} : 允许模式重复m~ n 

例如:

rw * \.python\.org  匹配 www.python.org 、.python.org 、wwwwwww.python.org

rw + \.python\.org  匹配 w.python.org ;但不能匹配 .python.org 

rw {3,4}\.python\.org  只能匹配www.python.org 和wwww.python.org 

 

re模块的内容

 

re模块中一些重要的函数:

  re.compile 将正则表达式转换为模式对象,可以实现更有效率的匹配。

  re.search 会在给定字符串中寻找第一个匹配给正则表式的子字符串。找到函数返回MatchObject(值为True),否则返回None(值为False) 。因为返回值的性质,所以该函数可以用在条件语句中:

if re.serch(pat, string):

print ‘found it !’

 

  re.math 会在给定字符串的开头匹配正则表达式。因此,re.math(p , python)返回真,re.math(p , www.python则返回假。

  re.split 会根据模式的匹配项来分割字符串。

>>> import re>>> some_text = 'alpha , beta ,,,gamma delta '>>> re.split('[,]+',some_text)['alpha ', ' beta ', 'gamma delta ']

 

  re. findall以列表形式返回给定模式的所有匹配项。比如,要在字符串中查找所有单词,可以像下面这么做:

>>> import re>>> pat = '[a-zA-Z]+'>>> text = '"Hm...err -- are you sure?" he said, sounding insecure.'>>> re.findall(pat,text)['Hm', 'err', 'are', 'you', 'sure', 'he', 'said', 'sounding', 'insecure']

 

  re.sub的作用在于:使用给定的替换内容将匹配模式的子符串(最左端并且重叠子字符串)替换掉。

>>> import re>>> pat = '{name}'>>> text = 'Dear {name}...'>>> re.sub(pat, 'Mr. Gumby',text)'Dear Mr. Gumby...'

 

  re.escape 函数,可以对字符串中所有可能被解释为正则运算符的字符进行转义的应用函数。

如果字符串很长且包含很多特殊字符,而你又不想输入一大堆反斜线,可以使用这个函数:

>>> re.escape('www.python.org')'www\\.python\\.org'>>> re.escape('but where is the ambiguity?')'but\\ where\\ is\\ the\\ ambiguity\\?'

 

 

 

匹配对象和组

 

简单来说,组就是放置在圆括号里内的子模块,组的序号取决于它左侧的括号数。组0就是整个模块,所以在下面的模式中:

‘There  (was a (wee) (cooper)) who (lived in Fyfe)’

包含组有:

0  There  was a  wee cooper  who  lived in Fyfe

1  was a  wee  cooper

2  wee

3  cooper

4  lived in Fyfe

 

re 匹配对象的重要方法

下面看实例:

复制代码
>>> import re>>> m = re.match(r'www\.(.*)\..{3}','www.python.org')>>> m.group()'www.python.org'>>> m.group(0)'www.python.org'>>> m.group(1)'python'>>> m.start(1)4>>> m.end(1)10>>> m.span(1)(4, 10)
复制代码

  group方法返回模式中与给定组匹配的字符串,如果没有组号,默认为;如上面:m.group()==m.group(0) ;如果给定一个组号,会返回单个字符串。

  start 方法返回给定组匹配项的开始索引,

  end方法返回给定组匹配项的结束索引加1

  span以元组(startend)的形式返回给组的开始和结束位置的索引。

 

----------------------------

正则表达式应该是不容易理解的一个知识点;python没意思的基础终于学完了。虽然学的不扎实,但大体有了个印象;后面的将会非常有意思,读取文件,编写图形窗口,连接数据库,web编程....


模块

前面有简单介绍如何使用import从外部模块获取函数并且为自己的程序所用:

>>> import math>>> math.sin(0)  #sin为正弦函数0.0

 

模块是程序

任何python程序都可以作为模块导入。假设写如下程序,并且将它保存为以C:\python\hello.py

#hello.pyprint "hello,world!"

下面通过python解释器调用:

>>> import sys>>> sys.path.append('c:/python')>>> import hellohello,world!

再来一次:

>>> import hello>>> 

怎么这次没结果?因为导入模块并不意味着在导入进执行某些操作。它们主要用于定义,比如变量、函数和类等。此外,因为只需要定义这些东西一次,导入模块多次和导入一次的效果是一样的。

 

 

模块用于定义

1、在模块中定义函数

假设我们编写了一个类似代码的模块,将其保存为hello2.py 文件。

#hello2.pydef hello():    print "hello, world !"

保存后,可以像下面这样导入:

>>> import hello2

模块会被执行,这意味着hello函数在模块的作用被定义了。因此可以通过以下方式来访问函数:

>>> hello2.hello()

hello.world!

 

 

2、在模块中增加测试代码

模块用来定义函数、类和其他内容,有时候在模块中添加一些检查模块本身是否正常工作的测试代码是非常有用的。 

复制代码
#hello3.pydef hello():    print "hello.world!"def test():    hello()if __name__ == '__main__': test()
复制代码

f __name__ == '__nain__' 解释

python文件的后缀为.py .py文件可以用来直接运行,就像一个独立的小程序;也可以用来作为模块被其它程序调用。

__name__是模块的内置属性,如果等于'__main__' 侧表示直接被使用,那么将执行方法test()方法;如果是被调用则不执行 if 判断后面的test()方法。

执行结果:

复制代码
>>> import hello3   #表示hello3模块被调用,不执行test方法,所以没有输出>>> hello3.hello()   #表示程序执行,调用test方法hello.world!>>> hello3.hello()   #这里是不是可以反复调用test方法 hello.world!
复制代码

 

 

 

让模块可用

前面的例子中,我们改变了sys.path,其中包含了一个目录列表,解释器在该列表中查找模块。在理想情况下,一开始sys.path本身就应该包含正确的目录,有两方法可以做到这一点: 一是将模块放置在合适的位置,别外一种是告诉解释器去哪里查找需要的模块。

1、将模块放置在正确的位置

来看看python解释器会从哪里查找模块

复制代码
>>> import sys,pprint>>> pprint.pprint(sys.path)['', 'I:\\Python27\\Lib\\idlelib', 'C:\\Windows\\system32\\python27.zip', 'I:\\Python27\\DLLs', 'I:\\Python27\\lib', 'I:\\Python27\\lib\\plat-win', 'I:\\Python27\\lib\\lib-tk', 'I:\\Python27', 'I:\\Python27\\lib\\site-packages', 'c:/python']
复制代码

尽管这些目录下都可以被找到,但site-packages 目录是最佳选择。

 

 

2、告诉编译器去哪里找

以下情况是告诉编译器去哪儿找的原因:

  ** 不希望将自己的模块填满python解释器的目录

  ** 没有在python解释器目录中存储文件的权限

  ** 想将模块放到其它位置

编辑sys.path ,前面就已经使用了

>>> import sys>>> sys.path.append('c:/python')

但更优雅的做法是配置pythonpath环境变量,方法和配置java 环境变量类似。

 

 

文档

模块信息的自然来源是文档,除了通过python书籍或标准python文档来查看某个函数的含义,也可以通过下面方式: 

复制代码
>>> print range.__doc__range([start,] stop[, step]) -> list of integersReturn a list containing an arithmetic progression of integers.range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.When step is given, it specifies the increment (or decrement).For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!These are exactly the valid indices for a list of 4 elements.
复制代码

这样就获得了关于range函数的精确描述。

 

 

time 模块

time模块所包括的函数能够实现 以下功能:获得当前时间,操作时间和日期,从字符串读取时间以及格式化时间为字符串。

time模块中重要的函数

 

 time.asctime将当前时间格式化为字符串:

>>> time.asctime()'Thu May 16 00:00:08 2013'

 

 

 

random模块

random模块包括返回随机的函数,可以用于模拟或者用于任何产生随机输出的程序。

random模块中的一些重要函数:

 

 

下面介绍使用random模块的例子,还需要用到time模块中的函数。

例1:首先获得代表时间间隔(2013年)限制的实数,这可以通过时间元组的方式来表示日期(使用 -1表示一周的某天,一年中某天和夏令时,以例让python自己计算),并且对这些元组调用mktime 

复制代码
from random import *from time import *data1 = (2013 ,1,1,0,0,0,-1,-1,-1)time1 = mktime(data1)data2 = (2014 ,1,1,0,0,0,-1,-1,-1)time2 = mktime(data2)#然后在这个范围内生成随机数>>> random_time = uniform(time1,time2)# 可以将数字转换成易读的日期形式>>> print asctime(localtime(random_time))Fri Jan 18 18:23:16 2013
复制代码

 

例2:下面一个例子,假设三个人打牌,首先要保证54张牌没有重复的,第人发手里18张(斗地主就不能平均分配了)。

复制代码
>>> values = range(1,13) + 'dwang xwang'.split()  #定义13个数字与大小王>>> suits = 'hei hong mei fang '.split()           # 定义牌的四种类型(黑、红、梅、方)>>> deck = ['%s of %s' %(v ,s ) for v in values for s in suits]  #循环嵌套将其循环组合>>> from pprint import pprint   #调用pprint 模块>>> pprint (deck [:18])         #输出18张牌['1 of hei', '1 of hong', '1 of mei', '1 of fang', '2 of hei', '2 of hong', '2 of mei', '2 of fang', '3 of hei', '3 of hong', '3 of mei', '3 of fang', '4 of hei', '4 of hong', '4 of mei', '4 of fang', '5 of hei', '5 of hong']#显然上面的输出太整齐,调用随机函数,随机一点>>> from random import shuffle>>> shuffle(deck)>>> pprint(deck[:18])['5 of fang', '6 of hong', '5 of mei', 'dwang of fang', 'xwang of fang', '10 of hong', '7 of mei', '12 of hong', '6 of hei', '12 of hei', '7 of hei', '8 of hei', '4 of fang', 'dwang of hei', '11 of hei', '12 of fang', '5 of hei', '2 of hong']
复制代码

不过,依然是有问题的,大小王不应该分类型(黑、红、梅、方),显然上面的结果不够完美。

re模块包含对 正则表达式。本章会对re模块主要特征和正则表达式进行介绍。

 

什么是正则表达式

正则表达式是可以匹配文本片段的模式。最简单的正则表达式就是普通字符串,可以匹配其自身。换包话说,正则表达式python 可以匹配字符串python 。你可以用这种匹配行为搜索文本中的模式,并且用计算后有值并发特定模式,或都将文本进行分段。

 

** 通配符

正则表达式可以匹配多于一个的字符串,你可以使用一些特殊字符创建这类模式。比如点号(.)可以匹配任何字符。在我们用window 搜索时用问号(?)匹配任意一位字符,作用是一样的。那么这类符号就叫 通配符。

 

** 对特殊字符进行转义

通过上面的方法,假如我们要匹配“python.org”,直接用用‘python.org’可以么?这么做可以,但这样也会匹配“pythonzorg”,这可不是所期望的结果。

好吧!我们需要对它进行转义,可以在它前面加上发斜线。因此,本例中可以使用“python\\.org”,这样就只会匹配“python.org”了。

 

** 字符集

我们可以使用中括号([ ])括住字符串来创建字符集。可以使用范围,比如‘[a-z]’能够匹配az的任意一个字符,还可以通过一个接一个的方式将范围联合起来使用,比如‘[a-zA-Z0-9]’能够匹配任意大小写字母和数字。

反转字符集,可以在开头使用^字符,比如‘[^abc]’可以匹配任何除了abc之外的字符。

 

** 选择符

有时候只想匹配字符串python 和 perl  ,可以使用选择项的特殊字符:管道符号(|) 。因此, 所需模式可以写成python|perl 。

 

** 子模式

但是,有些时候不需要对整个模式使用选择符---只是模式的一部分。这时可以使用圆括号起需要的部分,或称子模式。 前例可以写成 p(ython | erl)

 

** 可选项

在子模式后面加上问号,它就变成了可选项。它可能出现在匹配字符串,但并非必须的。

r(heep://)?(www\.)?python\.org

只能匹配下列字符:

http://www.python.org

http://python.org

www.python.org

python.org

 

** 重复子模式

(pattern)* : 允许模式重复0次或多次

(pattern)+ : 允许模式重复1次或多次

(pattern){m,n} : 允许模式重复m~ n 

例如:

rw * \.python\.org  匹配 www.python.org 、.python.org 、wwwwwww.python.org

rw + \.python\.org  匹配 w.python.org ;但不能匹配 .python.org 

rw {3,4}\.python\.org  只能匹配www.python.org 和wwww.python.org 

 

re模块的内容

 

re模块中一些重要的函数:

  re.compile 将正则表达式转换为模式对象,可以实现更有效率的匹配。

  re.search 会在给定字符串中寻找第一个匹配给正则表式的子字符串。找到函数返回MatchObject(值为True),否则返回None(值为False) 。因为返回值的性质,所以该函数可以用在条件语句中:

if re.serch(pat, string):

print ‘found it !’

 

  re.math 会在给定字符串的开头匹配正则表达式。因此,re.math(p , python)返回真,re.math(p , www.python则返回假。

  re.split 会根据模式的匹配项来分割字符串。

>>> import re>>> some_text = 'alpha , beta ,,,gamma delta '>>> re.split('[,]+',some_text)['alpha ', ' beta ', 'gamma delta ']

 

  re. findall以列表形式返回给定模式的所有匹配项。比如,要在字符串中查找所有单词,可以像下面这么做:

>>> import re>>> pat = '[a-zA-Z]+'>>> text = '"Hm...err -- are you sure?" he said, sounding insecure.'>>> re.findall(pat,text)['Hm', 'err', 'are', 'you', 'sure', 'he', 'said', 'sounding', 'insecure']

 

  re.sub的作用在于:使用给定的替换内容将匹配模式的子符串(最左端并且重叠子字符串)替换掉。

>>> import re>>> pat = '{name}'>>> text = 'Dear {name}...'>>> re.sub(pat, 'Mr. Gumby',text)'Dear Mr. Gumby...'

 

  re.escape 函数,可以对字符串中所有可能被解释为正则运算符的字符进行转义的应用函数。

如果字符串很长且包含很多特殊字符,而你又不想输入一大堆反斜线,可以使用这个函数:

>>> re.escape('www.python.org')'www\\.python\\.org'>>> re.escape('but where is the ambiguity?')'but\\ where\\ is\\ the\\ ambiguity\\?'

 

 

 

匹配对象和组

 

简单来说,组就是放置在圆括号里内的子模块,组的序号取决于它左侧的括号数。组0就是整个模块,所以在下面的模式中:

‘There  (was a (wee) (cooper)) who (lived in Fyfe)’

包含组有:

0  There  was a  wee cooper  who  lived in Fyfe

1  was a  wee  cooper

2  wee

3  cooper

4  lived in Fyfe

 

re 匹配对象的重要方法

下面看实例:

复制代码
>>> import re>>> m = re.match(r'www\.(.*)\..{3}','www.python.org')>>> m.group()'www.python.org'>>> m.group(0)'www.python.org'>>> m.group(1)'python'>>> m.start(1)4>>> m.end(1)10>>> m.span(1)(4, 10)
复制代码

  group方法返回模式中与给定组匹配的字符串,如果没有组号,默认为;如上面:m.group()==m.group(0) ;如果给定一个组号,会返回单个字符串。

  start 方法返回给定组匹配项的开始索引,

  end方法返回给定组匹配项的结束索引加1

  span以元组(startend)的形式返回给组的开始和结束位置的索引。

 

----------------------------

正则表达式应该是不容易理解的一个知识点;python没意思的基础终于学完了。虽然学的不扎实,但大体有了个印象;后面的将会非常有意思,读取文件,编写图形窗口,连接数据库,web编程....

原创粉丝点击