Python 基础知识快速入门学习

时间:2022-06-30 15:40:24

 

               Python 基础知识快速入门学习                                               

 

ubuntu创建 ***.py ,运行python   ***.py

1、print 打印

1.1、输入打印

1)、打印hell oword :

print “hello word”  

 2)、打印 3.14

      print 3.14

1.2、计算打印

1)、1+2*3

print 1+2*3   (7)

1.3、比较打印

1)比较2和3

print 2>3    (false)

print 2<3    (true)

2、变量

name = ‘Crossin’  (字符串,需要用’’或者””引起来)

myVar = 123             (整数)

price = 5.99                       (浮点数)

visible = True                   (布尔运算)

 

‘=’ 号的作用是赋值左边变量

 

a=123

print a    (123)

 

a=’hello’

print a  (hello)

 

value = 3*4

print value  (12)

 

value =2 <5

print value  (true)

 

name = input()

print name

 

print “Who do you think I am ?”

you = input()

print “oh,yes ! I am ”

print you

 

3、运算

>:大于 <:小于 >=:大于等于 <=:小于等于 ==:等于。比较两个值是否相等。之所以用两个等号,是为了和变量赋值区分开来。!=:不等与not:逻辑“非”。如果x 为True,则not x 为False and:逻辑“与”。如果x 为True,且y 为True,则x and y 为True or:逻辑“或” 。如果x、y中至少有一个为True,则x or y 为True

 

num = 10

print 'Guess what I think?'

answer = input()

 

result = answer<num

print 'too small?'

print result

 

result = answer>num

print 'too big?'

print result

 

result = answer==num

print 'equal?'

print result

 

4、if语句

if 语句的时候,会去判断它所带条件的真假。

“如果”为True,就会去执行接下来的内容。 “如果”为False,就跳过。

语法为:

if 条件: 选择执行的语句

特别说明:条件后面的冒号不能少,同样必须是英文字符特别特别说明: if 内部的语句需要有一个统一的缩进, 一般用4 个空格。python 用这种方法

替代了其他很多编程语言中的{}。你也可以选择1/2/3... 个空格或者按一下tab 键,但必须整 个文件中都统一起来。千万不可以tab 和空格混用,不然就会出现各种莫名其妙的错误。所 以建议都直接用4 个空格。

 

thisIsLove = input()

if thisIsLove: print " 再转身就该勇敢留下来 "

试试看?输入True,就会得到回答。 输入False,什么也没有。(如果你那里输出中文有问题, 请自行改成英文)

所以,我们的游戏可以这样改写:

 

num = 10

print 'Guess what I think?'

answer = input()

if answer<num:

print 'too small!'

if answer>num:

print 'too big!'

if answer==num:

print 'BINGO!'

 

4、while 语句

程序执行到while 处,“当”条件为True 时,就去执行while 内部的代码,“当”条件为False 时,就跳过。

语法为:

while 条件: 循环执行的语句

 if 一样,注意冒号,注意缩进。

a = 1 #先 a设为 1

while a != 0: #a 不等于0 就一直做

     print "please input"

    a = input()

print "over注意,这里出现了两层缩进,要保持每层缩进的空格数相同。

 

5、随机数random

 

之前我们用了很多次的print 和input 方法,它们的作用是实现控制台的输入和输出。除此 之外,python 还提供了很多模块,用来实现各种常见的功能,比如时间处理、科学计算、 网络请求、随机数等等等等。今天我就来说说,如何用python 自带的随机数模块,给我们 的小游戏增加不确定性。

引入模块的方法:

from 模块名 import 方法名

看不懂没关系, 这东西以后我们会反复用到。 今天你只要记住, 你想要产生一个随机的整数, 就在程序的最开头写上:

from random import randint

之后你就可以用randint 来产生随机数了。

还记得input 后面的()吗,我们使用randint 的时候后面也要有()。而且,还要在括号中提供 两个数字,先后分别是产生随机整数范围的下限和上限。例如:

randint(5, 10)

这样将会产生一个 5  10 之间(包括 5  10)的随机整数。

 

写一个才随机数的小游戏:

from random import randint

num = randint(1,10)

print “guss 1~10 what num I think ”

answer = input()

result = answer == num

while not result:

                print“wrong”

                print“go ahead”

                answer= input()

                 result = answer == num

print “God you  cangusss it !”

6、变量2深入补充

变量这东西,我们已经用过。有了变量,就可以存储和计算数据。今天来讲点变量的细节。

#==== 变量命名规则====# 变量名不是你想起就能起的:

第一个字符必须是字母或者下划线“_”

剩下的部分可以是字母、下划线“_”或数字(0-9)

变量名称是对大小写敏感的,myname 和myName 不是同一个变量。 几个有效的栗子:

i

__my_name

name_23

a1b2_c3

几个坏掉的栗子(想一下为什么不对) :

2things

this is spaced out

my-name

#==== 变量的运算====#

我们前面有用到变量来存储数据:num = 10

answer = input()

也有用到变量来比较大小:answer < num

除此之外,变量还可以进行数学运算:a = 5 b = a + 3 c = a + b

python 中运算的顺序是,先把“=”右边的结果算出了,再赋值给左边的变量。下面这个例 子:a = 5 a = a + 3 print a 你会看到,输出了8,因为先计算出了右边的值为8,再把8 赋给左边的a。 通过这种方法,可以实现累加求和的效果。它还有个简化的写法:a += 3这个和a = a + 3是一样的。

于是,利用变量、 循环、累加,可以写一个程序, 来完成传说中高斯大牛在小时候做过的题:1+2+3+...+100=?从1 加到100 等于多少?

提示:你可以用一个变量记录现在加到几了,再用一个变量记录加出来的结果,通过while 来判断是不是加到100 了。

num =1;

sum =0;

 

while  num<=100 :

                sum=sum+num;

                num=num+1;

print sum

6、for 循环

for ... in ...

for 循环,则可以这么写:

for i in range(1, 101):

 print i

解释一下,range(1, 101)表示从1 开始,到101 为止(不包括101),取其中所有的整数。for i in range(1, 101) 就是说,把这些数,依次赋值给变量i。相当于一个一个循环过去,第一次i = 1,第二次i = 2,,,,直到i = 100。当i = 101 时跳出循环。所以,当你需要一个循环10 次的循环,你就只需要写:

for i in range(1, 11)

或者

for i in range(0, 10)

区别在于前者i 是从1 到10,后者i 是从0 到9。当然,你也可以不用i 这个变量名。 比如一个循环n 次的循环:

for count in range(0, n)

for 循环的本质是对一个序列中的元素进行递归。什么是序列,以后再说。先记住这个最简

单的形式:

for i in range(a, b)

 a 循环至 b-1

for I in range(0,100):

      print i

 

7、字符串

              

python 中最常用的字符串表示方式是引号(‘’)和双引号( "" )。我还是要再说:一定得 是英文字符!

'string'和“ string”的效果是一样的。

可以直接输出一个字符串print ‘good’

也可以用一个变量来保存字符串,然后输出str = ‘bad’print str

如果你想表示一段有英文引号或者双引号的文字, 那么表示这个字符串的引号就要与内 容区别开。

内容带有单引号,就用双引号表示 "It's good" 反之亦然You are a "BAD" man

python 中还有一种表示字符串的方法:三个引号(‘’‘)或者( """ 

在三个引号中,你可以方便地使用单引号和双引号,并且可以直接换行

'''

"What's your name?" Iasked.

"I'm Han Meimei."

'''

还有一种在字符串中表示引号的方法,就是用 ,可以不受引号的限制

\'表示引号, \" 表示双引号 ‘I\'ma \"good\" teacher ’

被称作转译字符,除了用来表示引号,还有比如用 表示字符串中的\ \n 表示字符串中的

还有个用处,就是用来在代码中换行,而不影响输出的结果:"this is the\

same line"

个字符串仍然只有一行,和

"this is thesame line" 是一,只是在代码中换了行。当你要写一行很长的代码时,这个会派上用场。

 

1.

He said, "I'm yours!"

 

print‘He said, "I'm yours!"  ’

 

2.

\\_v_//

print ‘’’\\\_v_//‘’‘

 

3.

Stay hungry,

stay foolish.

-- Steve Jobs

 

 

print ‘’’ Stay hungry,

stay foolish.

-- Steve Jobs

’’’

 

4.

*

***

*****

***

*

 

print ‘’’

*

***

*****

***

*

’’’

8、字符串格式化

我们在输出字符串的时候,如果想对输出的内容进行一些整理,比如把几段字符拼接起来, 或者把一段字符插入到另一段字符中间,就需要用到字符串的格式化输出。

1)先从简单的开始,如果你想把两段字符起来

str1 = 'good'

str2 = 'bye'

你可以

print str1 + str2

或者还可以把字符变量一个字符串相加

print 'very' + str1

print str1 + ' and ' + str2

2)但如果你想要把一个数字加到文字后面输出,比如这样

num = 18

print 'My age is' + num 程序就会报错。因为字符和数字不能直接用+相加。

一种解决方法是, str()把数字转换成字符串

print 'My age is' + str(18) 或

num = 18

print 'My age is' + str(num)

还有一种方法,就是用 %字符串行格式化

num = 18

print 'My age is %d' % num 出的候, %d 会被%后面的

My age is 18

这里, %d只能用来替换整数。如果你想格式化的数值是小数,要用%f print ‘Price is %f’ % 4.99

输出

Price is 4.990000

如果你想保留两位小数,需要在 f 前面加上条件:%.2f print ‘Price is %.2f’ % 4.99 输出

Price is 4.99

另外,可以用 %s来替换一段字符串

name = 'Crossin'

print '%s is a good teacher.' %name 输出

Crossin is a good teacher.

或者

print 'Today is %s.' % 'Friday'  输出

Today is Friday.

注意区分: 有引号的表示一段字符, 没有引号的就是一个变量,这个变量可能是字符, 也可 能是数字,但一定要和%所表示的格式相一致。

 

 

 

之前我们说到,可以用 %来构造一个字符串,比如

print '%s is easy to learn' % 'Python'

有时候,仅仅代入一个值不能满足我们构造字符串的需要。假设你现在有一组学生成绩的数据,你要输出这些数据。在一行中,既要输出学生的姓名,又要输出他的成绩。例如 Mike‘s score is 87.

Lily‘s score is 95.

在 python中,你可以这样实现:

print "%s's score is %d" % ('Mike', 87)

或者

name = ‘Lily’

score = 95

print "%s's score is %d" % (name, score)

无论你有多少个值需要代入字符串中进行格式化,只需要在字符串中的合适位置用对应格式的%表示,然后在后面的括号中按顺序提供代入的值就可以了。占位的 %和括号中的值在数 量上必须相等,类型也要匹配。

('Mike', 87) 这种用 ()表示的一组数据在 python 中被称为元组( tuple),是 python 的一种基本数据结构。

 

 

 

 

 

9、循环嵌套for循环

设想一样,如果我们要输出 5 个* ,用 for 循环要这么写

for i in range(0, 5):

print '*'

如果想让这 5 个* 在同一行,就在 print 语句后面加上逗号

for i in range(0, 5): print '*',

但如果我想要这样一个图形,怎么办?

* * * * *

* * * * *

* * * * *

* * * * *

* * * * *

当然,你可以循环 5 次,每次输出一行“ * * ** * ”。那如果再进一步,这样呢?

*

**

***

****

*****

除了你自己动手打好一个多行字符串外,也可以让程序帮我们解决这种问题,我们需要的是两个嵌套在一起的循环:

for i in range(0, 5):

for j in range(0, 5):

print i, j

第二个 for 循环在第一个 for 循环的内部,表示每一次外层的循环中,都要进行一遍内层的循环。看一下输出的结果:

0 0

0 1

0 2

0 3

0 4

1 0

...

4 4 内层循环中的 print 语句一共被执行了 25 次。 i 从 0 到 4 循环了 5 次。对应于每一个 i 的值,j 又做了从 0 到 4 五次循环。 所以 5*5 一共 25 次。

所以如果要输出一个 5*5 的方阵图案,我们可以

for i in range(0, 5):

for j in range(0, 5):

print '*',

print

注意:第二个 print 的缩进和内层的 for 是一样的,这表明它是外层 for 循环中的语句,每次 i 的循环中,它会执行一次。 print 后面没有写任何东西,是起到换行的作用,这样,每输出 5 *,就会换行。

要输出第二个三角图案时,我们需要根据当前外层循环的序数,设置内层循环应当执行的次数。

for i in range(0, 5): for j in range(0, i+1):

print '*',

print

内层的 j 每次从 0 到 i+1 进行循环。 这样,当第一次 i=0 时, j 就是 range(0,1),只输出 1 个* 。 而当最后一次 i=4 时, j 就是 range(0,5),输出 5 个*。

10、类型转换

字符串 整数 小数(浮点数)bool 类型

python 在定义一个变量时不需要给它限定类型。变量会根据赋给它的值,自动决定它的类 型。你也可以在程序中,改变它的值,于是也就改变了它的类型。例如

a = 1

print a

a = 'hello'

print a

a = True

print a

变量a 先后成为了整数、字符串、bool 类型。

虽然类型可以随意改变, 但当你对一个特定类型的变量进行操作时, 如果这个操作与它的数 据类型不匹配,就会产生错误。比如以下几行代码

print ‘Hello ’+1 print ‘hello%d’ % '123'

程序运行时会报错。因为第一句里,字符串和整数不能相加;第二句里,%d需要的是一个 整数, '123' 是字符串

这种情况下,python 提供了一些方法对数值进行类型转换:

int(x) # 把x 转换成整数float(x) # 把x 转换成浮点数str(x) # 把x 转换成字符串bool(x) # 把x 转换成bool 值

上述两个例子就可以写成:

print ‘Hello ’+str(1) print ‘hello%d’ % int('123')

以下等式的结果均为真:

int('123') == 123

float('3.3') == 3.3

str(111) == '111'

bool(0) == False

并不是所有的值都能做类型转换, 比如int('abc') 同样会报错,python 没办法把它转成一个整 数。

另外关于bool 类型的转换,我们会专门再详细说明。大家可以先试试以下结果的值,自己 摸索一下转换成bool 类型的规律:

bool(-123)   true

bool(0)     False

bool('abc')      true

bool('False')     true

bool('')     false

因为在python 中,以下数值会被认为是 False: 为 0 的数字,包括 00.0 空字符串,包括 ''"" 表示空值的 None 空集合,包括(),[],{} 其他的值都认为是True。

None 是python 中的一个特殊值,表示什么都没有,它和0、空字符、False、空集合都不一 样。关于集合,我们后面的课程再说。

所以,‘False’是一个不为空的字符串,当被转换成bool 类型之后,就得到True同样 bool(' ') 的结果是True,一个空格也不能算作空字符串。 bool('') 才是 False

 

11、函数

如果我们要自己写一个函数,就需要去定义它。python 里的关键字叫

def(define的缩写),格式如下:

def sayHello():

 print 'hello world!'

sayHello 是这个函数的名字,后面的括号里是参数,这里没有,表示不

需要参数。但括号和后面的冒号都不能少。下面缩进的代码块就是整个

函数的内容,称作函数体。

然后我们去调用这个函数:

sayHello()

得到和直接执行 print 'hello world!' 一样的结果。

12、函数的参数

如果我们希望自己定义的函数里允许调用者提供一些参数, 就把

这些参数写在括号里,如果有多个参数,用逗号隔开,如:

def sayHello(someone):

 print someone + ' says Hello!'

或者

def plus(num1, num2): 

print num1+num2

参数在函数中相当于一个变量, 而这个变量的值是在调用函数的时候被

赋予的。在函数内部,你可以像过去使用变量一样使用它。

调用带参数的函数时,同样把需要传入的参数值放在括号中, 用逗号隔

开。要注意提供的参数值的数量和类型需要跟函数定义中的一致。 如果

这个函数不是你自己写的,你需要先了解它的参数类型,才能顺利调用

它。

比如上面两个函数,我们可以直接传入值:

sayHello('Crossin') 还是注意,字符串类型的值不能少了引号。

或者也可以传入变量:

x = 3

 y = 4

plus(x, y)

在这个函数被调用时, 相当于做了num1=x, num2=y 这么一件事。 所以

结果是输出了7

 

13、函数应用示例,判断值大小返回结果

 

def isEqual(num1, num2): 

if num1<num2:

  print 'too small'

 return False;

 if num1>num2:

 print 'too big' 

return False;

 if num1==num2: 

print 'bingo' 

return True

from random import randint

num = randint(1, 100)

print 'Guess what I think?'

bingo = False

while bingo == False:

 answer = input()

                bingo = isEqual(answer, num)

 

14、if,elif, else

之前说的if,是: “如果”条件满足,就做xxx,否则就不做。

else 顾名思义,就是: “否则”就做yyy。

当if 后面的条件语句不满足时,与之相对应的else 中的代码块将被执

行。

if a == 1: 

                print 'right' else  print 'wrong'

elif 意为else if ,含义就是: “否则如果 ”条件满足,就做yyy。elif后面

需要有一个逻辑判断语句。

当if 条件不满足时,再去判断elif 的条件,如果满足则执行其中的代码

块。

if a == 1:

 print 'one'

elif a == 2:

 print 'two'

if, elif, else 可组成一个整体的条件语句。

if 是必须有的;

elif 可以没有,也可以有很多个,每个 elif 条件不满足时会进入下一个

elif 判断;

else 可以没有,如果有的话只能有一个,必须在条件语句的最后。

if a == 1:

 print 'one'

elif a == 2:

 print 'two'

elif a == 3:

 print 'three'

else:

 print 'too many'

我们昨天刚改写的小游戏中的函数isEqual ,用了三个条件判断,我们

可以再改写成一个包含if...elif...else 的结构:

def isEqual(num1, num2): 

if num1<num2:

 print 'too small' 

return False 

elif num1>num2: 

print 'toobig' 

return False 

else: 

print 'bingo' 

return True

15、list列表

今天要说一个新概念--list,中文可以翻译成列表,是用来处理一组有序

项目的数据结构。

for i in range(1, 10): #此处略过数行代码

看出来list 在哪里了吗?你试一下:

print range(1,10)

得到的结果是:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

这就是一个 list。它由 range 产生。把上面那个 for 循环语句写成:

l = range(1, 10)

 for i in l:

效果是一样的。

于是可以看出,for 循环做的事情其实就是遍历一个列表中的每一项,

每次循环都把当前项赋值给一个变量(这里是i),直到列表结束。

我们也可以定义自己的列表,格式就是用中括号包围、逗号隔开的一组

数值:

l = [1, 1, 2, 3, 5, 8, 13]

可以用print 输出这个列表:

print l

同样也可以用for...in 遍历这个列表,依次输出了列表中的每一项:

for i in l:

 print l,

列表中的元素也可以是别的类型,比如:

l = ['meat', 'egg', 'fish', 'milk']

甚至是不同类型的混合:

l = [365, 'everyday', 0.618, True]

l 身为一个列表,有一些特有的功能:

 

假设我们现在有一个list:

l = [365, 'everyday', 0.618, True]

除了用for...in 遍历l 中的元素,我们还能做点啥?

1).访问list 中的元素

list 中的每个元素都对应一个递增的序号。与现实中习惯的序号不同在

于,计算机中的计数通常都是从 0 开始,python 也不例外。

要访问l 中的第1 个元素365,只要用l[0]就可以了。依次类推,

print l[1] 就会输出 'everyday'

注意,你不能访问一个不存在的元素,比如 l[10],程序就会报错,提示

你index 越界了。

2).修改list 中的元素

修改list 中的某一个元素,只需要直接给那个元素赋值就可以了:

l[0] = 123

输出l,得到[123, 'everyday', 0.618, True] ,第 1 个元素已经从 365 被

改成了123。

3).向list 中添加元素

list 有一个append 方法,可以增加元素。以l 这个列表为例,调用的方

法是:

l.append(1024)

输出l,你会看到[123, 'everyday', 0.618, True, 1024] ,1024 被添加到

了l,成为最后一个元素。(第一个元素在上一步被改成了123)

然后同样可以用l[4]得到1024 。

4).删除list 中的元素

删除list 中的某一个元素,要用到del:

del l[0]

输出l,得到['everyday', 0.618, True, 1024] 。这时候再调用 l[0],会得

到'everyday',其他元素的序号也相应提前。

以上这些命令,你可以直接在python shell 中尝试

 

 

 

 

 

16、列表的索引和切片

我打算从今天开始,每天说一点这个小游戏的做法。方法有很多种,我

只是提供一种参考。 你可以按照自己喜欢的方式去做, 那样她才是属于

你的游戏。

先说一下方向的设定。我的想法比较简单,就是左中右三个方向,用字

符串来表示。射门或者扑救的时候,直接输入方向。所以这里我准备用

raw_input 。有同学是用1-8 的数字来表示八个方向,每次输入一个数

字,这也是可以的。不过这样守门员要扑住的概率可就小多了。

至于电脑随机挑选方向,如果你是用数字表示,就用我们之前讲过的

randint 来随机就行。不过我这次打算用random 的另一个方法:choice。

它的作用是从一个list 中随机挑选一个元素。

于是,罚球的过程可以这样写:

from random import choice

print 'Choose one side to shoot:'

print 'left, center, right'

you = raw_input()     #你选择的方向

print 'You kicked ' + you direction = ['left', 'center','right']

com = choice(direction)  #电脑随机抽取方向

 print 'Computer saved' + com

 if you != com:      #比对比们的方向

                print 'Goal!'

else:

 print 'Oops...'

反之亦然,不赘述。

list 有两类常用操作:索引(index) 和切片(slice) 。

我们说的用 []加序号访问的方法就是索引操作

除了指定位置进行索引外,list 还可以处理负数的索引。

例子:

l = [365, 'everyday', 0.618, True]

l[-1]表示 l 中的最后一个元素。

l[-3]表示倒数第 3 个元素。

切片操作符是在[]内提供一对可选数字,用:分割。冒号前的数表示切片

的开始位置,冒号后的数字表示切片到哪里结束。 同样,计数从 0开始。

注意,开始位置包含在切片中,而结束位置不包括

l[1:3]

得到的结果是 ['everyday', 0.618] 

如果不指定第一个数,切片就从列表第一个元素开始。

如果不指定第二个数,就一直到最后一个元素结束。

都不指定,则返回整个列表的一个拷贝。

l[:3] l[1:] l[:]

同索引一样,切片中的数字也可以使用负数。比如:

l[1:-1]

得到['everyday',0.618]

 

17、字符串的分割

我们先从最基本的开始。 假设你现在拿到了一个英语句子, 需要把这个

句子中的每一个单词拿出来单独处理。

sentence = 'I am an Englist sentence'

这时就需要对字符串进行分割。

sentence.split()

split()会把字符串按照其中的空格进行分割,分割后的每一段都是一个

新的字符串,最终返回这些字符串组成一个list。于是得到

['I', 'am', 'an', 'Englist','sentence']

原来字符串中的空格不再存在。

除了空格外,split()同时也会按照换行符\n,制表符\t 进行分割。所以应

该说,split 默认是按照空白字符进行分割。

之所以说默认,是因为split 还可以指定分割的符号。比如你有一个很

长的字符串

section = 'Hi. I am the one. Bye.'

通过指定分割符号为'.',可以把每句话分开

section.split('.')

得到

['Hi', ' I am the one', ' Bye', '']

这时候,'.'作为分割符被去掉了,而空格仍然保留在它的位置上。

注意最后那个空字符串。每个 '.'都会被作为分割符,即使它的后面没有

其他字符,也会有一个空串被分割出来。例如

'aaa'.split('a')

将会得到['', '', '', ''] ,由四个空串组成的list

18、字符串连接

join和split正好相反:split 是把一个字符串分割成很多 字符串组成的list ,而join 则是把一个list 中的所有字符串连接成一个字符串。

join 的格式有些奇怪,它不是list 的方法,而是字符串的方法。首先你需要有一个字符串 作为list 中所有元素的连接符,然后再调用这个连接符的join 方法,join 的参数是被连 接的list :

s = ';'

li = ['apple', 'pear', 'orange']

fruit = s.join(li)

print fruit

得到结果 'apple;pear;orange' 。 从结果可以看到,分号把list 中的几个字符串都连接了起来。

你也可以直接在shell 中输入:

';'.join(['apple', 'pear', 'orange'])

得到同样的结果。

用来连接的字符串可以是多个字符,也可以是一个空串:

''.join(['hello', 'world'])

得到 'helloworld' ,字符串被无缝连接在一起

19、字符串和列表比较

1).遍历 通过for...in 可以遍历字符串中的每一个字符。

word = 'helloworld'

for c in word:

print c

2).索引访问 通过[] 加索引的方式,访问字符串中的某个字符。

print word[0]

print word[-2]

 list 不同的是,字符串能通过索引访问去更改其中的字符

word[1] = 'a' 这样的赋值是错误的。

3).切片 通过两个参数,截取一段子串,具体规则和list 相同。

print word[5:7]

print word[:-5]

print word[:]

4).连接字符join 方法也可以对字符串使用,作用就是用连接符把字符串中的每个字符重新连接成一个 新字符串。不过觉得这个方法有点鸡肋,不知道在什么场景下会用到。

20、读文件

打开一个文件的命令很简单:

file(' 文件名')

这里的文件名可以用文件的完整路径, 也可以是相对路径。 因为我们把要读取的文件和代码 放在了同一个文件夹下,所以只需要写它的文件名就够了。

f = file('data.txt')

但这一步只是打开了一个文件, 并没有得到其中的内容。 变量f 保存了这个文件, 还需要去 读取它的内容。你可以通过read() 函数把文件内所有内容读进一个字符串中。

data = f.read()

做完对文件的操作之后,记得用close() 关闭文件,释放资源。虽然现在这样一个很短的程 序,不做这一步也不会影响运行结果。但养成好习惯,可以避免以后发生莫名的错误。

完整程序示例:

f = file('data.txt')

data = f.read()

print data

f.close()

读取文件内容的方法还有

readline() # 读取一行内容

readlines() # 把内容按行读取至一个list 中

去替换程序的第二行,看看它们的区别

 

21、写文件

打开文件我们昨天已经讲过。但python 默认是以只读模式打开文件。如果想要写入内容, 在打开文件的时候需要指定打开模式为写入:

f = file('output.txt', 'w')

'w' 就是 writing ,以这种模式打开文件,原来文件中的内容会被你新写入的内容覆盖掉, 如果文件不存在,会自动创建文件。 不加参数时, file 为你默认为'r' ,reading ,只读模式,文件必须存在,否则引发异常。 另外有一种模式是 'a' appending 。它也是一种写入模式,但你写入的内容不会覆盖之前的内容,而是添加到文件中。

打开文件还有一种方法,就是open() ,用法和 file() 是一致的。

写入内容的方法同样简单:

f.write('a string you want to write')

write 的参数可以是一个字符串,或者一个字符串变量。

示例程序:

data = 'I will be in a file.\nSocool!'

out = open('output.txt', 'w')

out.write(data)

out.close()

在你的程序保存目录下,打开output.txt 就会看到结果。

 

22、处理文件里面的数据

比如我现在拿到一份文档, 里面有某个班级里所有学生的平时作业成绩。 因为每个人交作业 的次数不一样, 所以成绩的数目也不同, 没交作业的时候就没有分。 我现在需要统计每个学 生的平时作业总得分。

看一下我们的文档里的数据:

#-- scores.txt

刘备23 35 44 47 51

关羽60 77 68

 张飞 97 99 89 91

诸葛亮100

曹操100 100 100 100 100

1).先把文件读进来:

f = file('scores.txt')

2).取得文件中的数据。因为每一行都是一条学生成绩的记录,所以用readlines ,把每 一行分开,便于之后的数据处理:

lines = f.readlines()

f.close()

提示:在程序中,经常使用print 来查看数据的中间状态, 可以便于你理解程序的运行。 比如这里你可以print lines ,看一下内容被存成了什么格式。

3).对每一条数据进行处理。按照空格,把姓名、每次的成绩分割开:

for line in lines:

data = line.split()

接下来的4、5两个步骤都是针对一条数据的处理,所以都是在for 循环的内部。

4).整个程序最核心的部分到了。如何把一个学生的几次成绩合并,并保存起来呢?我的 做法是:对于每一条数据, 都新建一个字符串, 把学生的名字和算好的总成绩保存进去。 最后再把这些字符串一起保存到文件中:

sum = 0

for score in data[1:]:

sum += int(score)

result = '%s\t: %d\n' % (data[0], sum)

这里几个要注意的点: 对于每一行分割的数据,data[0] 是姓名,data[1:] 是所有成绩组成的列表。

每次循环中,sum都要先清零 score 是一个字符串,为了做计算,需要转成整数值 int 。 result 中,我加了一个制表符 \t 和换行符 \n ,让输出的结果更好看些。

5. 得到一个学生的总成绩后,把它添加到一个list 中。

results.append(result)

results 需要在循环之前初始化 results = []

6. 最后,全部成绩处理完毕后,把results 中的内容保存至文件。因为results 是一个 字符串组成的list ,这里我们直接用 writelines 方法

output = file('result.txt', 'w')

output.writelines(results)

outpus.close()

大功告成,打开文件检验一下结果吧。

以下是完整程序, 把其中print 前面的注释符号去掉, 可以查看关键步骤的数据状态。 不过 因为字符编码的问题,list 的中文可能会显示为你看不懂的字符。

f = file('scores.txt')  

lines = f.readlines()   

#print lines

f.close()

results = []

for line in lines:

#print line

data = line.split()  

#print data  

sum = 0

for score in data[1:]:

sum += int(score)

                result = '%s \t: %d\n' %(data[0], sum)

#print result

results.append(result)

#print results

output = file('result.txt', 'w')

output.writelines(results)

output.close()

 

 

23、break   and   continue

如果在循环条件仍然满足或序列没有遍历完的时候, 想要强行跳出循环, 就需要用到break

语句。

while True:

a = raw_input()

if a == 'EOF':

break

上面的程序不停接受用户输入。当用户输入一行“ EOF”时,程序结束。

for i in range(10):

a = raw_input()

if a == 'EOF':

break

break 是彻底地跳出循环,而 continue 只是略过本次循环的余下内容,直接进入下一次循

环。

在我们前面写的那个统计分数的程序里,如果发现有成绩不足 60 分,就不记入总成绩。当

然,你可以用 if 判断来实现这个效果。但我们今天要说另一种方法:continue 。

for score in data[1:]:

point =int(score)

if point< 60:

continue

sum += point

注意:无论是 continue 还是 break,其改变的仅仅是当前所处的最内层循环的运行,如果外

层还有循环,并不会因此略过或跳出。

24、异常处理

在程序运行时,如果我们的代码引发了错误,python 就会中断程序,并且输出错误提示。

比如我们写了一句:

print int('0.5')

运行后程序得到错误提示:

Traceback (most recent call last):

File "C:/Python27/test.py", line 1, in<module>

print int('0.5')

ValueError: invalid literal for int() with base 10: '0.5'

意思是, test.py 这个文件,第 1 行, print int('0.5') 这里,你拿了一个不是 10 进制

能够表示的字符,我没法把它转成 int 值。

上面的错误可以避免,但在实际的应用中,有很多错误是开发者无法控制的,例如用户输

入了一个不合规定的值,或者需要打开的文件不存在。这些情况被称作“异常”,一个好

的程序需要能处理可能发生的异常,避免程序因此而中断。

例如我们去打开一个文件:

f = file('non-exist.txt')

print 'File opened!'

f.close()

假如这个文件因为某种原因并没有出现在应该出现的文件夹里,程序就会报错:

IOError: [Errno 2] No such file or directory:'non-exist.txt'

程序在出错处中断,后面的print 不会被执行。

在python 中,可以使用 try...except 语句来处理异常。做法是,把可能引发异常的语句

放在try- 块中,把处理异常的语句放在except- 块中。

把刚才那段代码放入try...except 中:

try:

f = file('non-exist.txt')

print 'File opened!'

f.close()

except:

print 'File not exists.'

print 'Done'

当程序在try 内部打开文件引发异常时,会跳过try 中剩下的代码,直接跳转到except 中

的语句处理异常。 于是输出了 “Filenot exists. ”。如果文件被顺利打开, 则会输出 “File

opened! ”,而不会去执行except 中的语句。

但无论如何,整个程序不会中断,最后的“ Done”都会被输出

在try...except 语句中,try 中引发的异常就像是扔出了一只飞盘, 而except 就是一只灵

敏的狗,总能准确地接住飞盘。

 

25、字典

字典这种数据结构有点像我们平常用的通讯录,有一个名字和这个名字对应的信息。在字

典中,名字叫做“键”对应的内容信息叫做“值”。字典就是一个键/ 值对的集合。

它的基本格式是 key 是键, alue 是值)

d = {key1 : value1, key2 : value2 }

值对用冒号分割,每个对之间用逗号分割,整个字典包括在花括号中。

关于字典的键要注意的是:

1. 键必须是唯一的;

2. 键只能是简单对象,比如字符串、整数、浮点数、bool 值。

list 就不能作为键,但是可以作为值。

举个简单的字典例子:

score = {

' 萧峰': 95,

' 段誉': 97,

' 虚竹': 89

}

python 字典中的键/ 值对没有顺序, 我们无法用索引访问字典中的某一项, 而是要用键来访

问。

print score[' 段誉']

注意,如果你的键是字符串, 通过键访问的时候就需要加引号, 如果是数字作为键则不用。 字典也可以通过 for...in 遍历:

for name in score :

print score[name]

注意,遍历的变量中存储的是字典的键。

如果要改变某一项的值,就直接给这一项赋值:

score[' 虚竹 '] = 91

增加一项字典项的方法是,给一个新键赋值:

score[' 慕容复 '] = 88

删除一项字典项的方法是 del 

del score[' 萧峰 ']

注意,这个键必须已存在于字典中。

如果你想新建一个空的字典,只需要 :

d = {}

 

 

 

26、模块

python 自带了功能丰富的标准库, 另外还有数量庞大的各种第三方库。 使用这些“巨人的”

代码,可以让开发事半功倍,就像用积木一样拼出你要的程序。

使用这些功能的基本方法就是使用模块。通过函数,可以在程序里重用代码;通过模块,

则可以重用别的程序中的代码。

模块可以理解为是一个包含了函数和变量的py 文件。在你的程序中引入了某个模块,就可

以使用其中的函数和变量。 来看一个我们之前使用过的模块:

import random

import 语句告诉 python ,我们要用 random 模块中的内容。然后便可以使用 random 中的方法,比如:

random.randint(1, 10)

random.randchoic([1, 3, 5])

注意,函数前面需要加上“ random. ”,这样 python 才知道你是要调用 random 中的方法。

想知道 random 有哪些函数和变量,可以用 dir() 方法:

dir(random)

如果你只是用到 random中的某一个函数或变量,也可以通过 from...import... 指明:

from math import pi

print pi

为了便于理解和避免冲突,你还可以给引入的方法换个名字:

from math import pi as math_pi

print math_pi

想要了解python 有哪些常用库,可自行搜索。

 

27、给函数提供默认参数

 

 

def hello(name):

print 'hello ' + name

然后我们去调用这个函数:

hello('world')

程序就会输出

hello world

如果很多时候, 我们都是用world 来调用这个函数,少数情况才会去改参数。那么,我们就 可以给这个函数一个默认参数:

def hello(name = 'world'):

print 'hello ' + name

当你没有提供参数值时,这个参数就会使用默认值;如果你提供了,就用你给的。

这样,在默认情况下,你只要调用

hello()

就可以输出

hello world

同样你也可以指定参数:

hello('python')

输出

hello python

注意,当函数有多个参数时, 如果你想给部分参数提供默认参数, 那么这些参数必须在参数的末尾。比如:

def func(a, b=5) 是正确的

def func(a=5, b) 就会出错

 

 

 

 

28、面向对象

面向对象编程最主要的两个概念就是: 类(class )和对象 (object )

是一种抽象的型,而象是型的例。

举个现实的例子: “笔”作为一个抽象的概念, 可以被看成是一个类。 而一支实实在在的笔, 则是“笔”这种类型的对象。

一个类可以有属于它的函数,这种函数被称为类的“方法”。一个类/ 对象可以有属于它的 变量,这种变量被称作“域”。 域根据所属不同, 又分别被称作“类变量”和“实例变量”。

继续笔的例子。 一个笔有书写的功能, 所以“书写”就是笔这个类的一种方法。 每支笔有自 己的颜色,“颜色”就是某支笔的域,也是这支笔的实例变量。

而关于“类变量”, 我们假设有一种限量版钢笔, 我们为这种笔创建一种类。 而这种笔的“产 量”就可以看做这种笔的类变量。 因为这个域不属于某一支笔, 而是这种类型的笔的共有属 性。

域和方法被合称为类的属性。

python 是一种高度面向象的言,它其中的所有西其都是。所以我们之前也一 直在使用着对象。看如下的例子:

1). s = 'how are you'           #s 被赋值后就是一个字符串类型的对象

2). l = s.split()                      #split 是字符串的方法,这个方法返回一个list 类型的对象 5. #l 是一个list 类型的对象

 dir() 方法可以看一个 / 量的所有属性:

 dir(s)

 dir(list)

 

现在我们创建一个类:

class MyClass:

pass

 mc = MyClass()

 print mc

关键字 class加上类名用来创建一个类。 之后缩进的代码块是这个类的内部。 在这里,  pass 句,表示一个空的代码块

类名加圆括号 () 的形式可以创建一个类的实例, 也就是被称作对象的东西。 我们把这个对象 赋值给变量 mc。于是, mc现在就是一个MyClass 类的对象。

看一下输出结果:

<__main__.MyClass instance at 0x7fd1c8d01200>

 

这个意思就是说 mc__main__ MyClass 来的一个例( instance ),后面的一串十六制的数字是象的内存地址。

我们给这个类加上一些域:

 class MyClass:

 name = 'Sam'

 

 def sayHi(self):

print 'Hello%s' % self.name

 

 mc = MyClass()

 print mc.name

 mc.name = 'Lily'

 mc.sayHi()

我们给 MyClass 增加了一个类变 name并把它的值设为'Sam' 。然后又增加了一个类方 法sayHi 。

调用类变量的方法是“对象 . 变量名”。你可以得到它的值,也可以改变它的值。

注意到,方法和我之前定的函数区在于,第一个参数必须为 self 。而在调用类方 法的时候,通过“对象. 方法名() ”格式进行调用,而不需要额外提供self 这个参数的值。 self 在类方法中的值,就是你调用的这个对象本身。

输出结果:

1. Sam

2. Hello Lily

之后,在你需要用到 MyClass 这种类型对象的地方,就可以创建并使用它。

 

用一个例子来展示两种程序设计方式的不同。 假设我们有一辆汽车,我们知道它的速度(60km/h) ,以及 A、B两地的距离 (100km) 。要算出 开着这辆车 A地到 B地花时间。(很像小学数学题是吧?)

面向程的方法

 speed = 60.0

distance = 100.0

 time = distance /speed

print time

 

面向象的方法:

 class Car:

 speed = 0

def drive(self, distance):

 time = distance / self.speed

 print time

 

car = Car()

car.speed = 60.0

car.drive(100.0)

看上去似乎面向对象没有比面向过程更简单,反而写了更多行代码。 但是,如果我们让题目再稍稍复杂一点。假设我们又有了一辆更好的跑车,它的速度是

150km/h,然后我们除了想从 A到B,还要从 B到 C(距离200km)。要求分别知道这两种车 在这两段路上需要多少时间。

面向程的方法:

speed1 = 60.0

distance1 = 100.0

 time1 = distance1/ speed1

 print time1

 

distance2 = 200.0

time2 = distance2 / speed1

 print time2

 

 speed2 = 150.0

time3 = distance1 / speed2

 print time3

 

 time4 = distance2/ speed2

 print time4

面向象的方法:

class Car:

speed = 0

defdrive(self, distance):

 time = distance / self.speed

                                 print time

 

 car1 = Car()

car1.speed = 60.0

 car1.drive(100.0)

 car1.drive(200.0)

 

car2 = Car()

 car2.speed = 150.0

 car2.drive(100.0)

car2.drive(200.0)

 

对比两种方法面向程把数据和理数据的算全部放在一起, 当功能复杂之后, 就会显 得很混乱, 且容易产生很多重复的代码而面向象,把一数据和这类数据的方法封装在一个中,程序的构更清晰,不同的功能之相互独立。 这样更有利于进行模块化 的开发方式。

 

 

我们就来举一个稍稍再复杂一点的例子。

仍然是从 A地到 B地,这次除了有汽车,我们还有了一辆自行车! 自行和汽有着相同的属性:速度( speed)。有一个相同的方法( drive ),来输出行 驶/ 骑行一段距离所花的时间。次我增加一个属性:每公里油耗( fuel )。 而在汽车行驶一段距离的方法中,除了要输出所花的时间外,还要输出所需的油量。

面向过程的方法, 你可能需要写两个函数, 然后把数据作为参数传递进去, 在调用的时候要 搞清应该使用哪个函数和哪些数据。 有了面向对象, 你可以把相关的数据和方法封装在一起, 并且可以把不同类中的相同功能整合起来。 这就需要用到面向对象中的另一个重要概念

承。

我们要使用的方法是, 建一个叫做 Vehicle ,表示某种, 它包含了汽车和自行车所 共有的东西:速度,行的方法然后 Car  Bike  Vehicle,即作为 它的子类。在每个子类中,可以分别添加各自独有的属性。

Vehicle 被称基本或超 Car  Bike 被成为导或子

class Vehicle:

 def __init__(self, speed):       #__init__ 函数会在类被创建的时候自动调用, 用来初始化类

self.speed = speed    

 

 def drive(self, distance):

print 'need %fhour(s)' % (distance / self.speed)

 

 classBike(Vehicle):      #就是说Bike 是继承自 Vehicle 中的子类。

 pass             #因为 Bike 不需要有额外的功 能,所以用 pass 在类中保留空块,什么都不用写。

 

 

class Car(Vehicle):

 def __init__(self,speed, fuel):    #我们又重新定义了 __init__ 和 drive 函数,这样会覆盖掉它继承自 Vehicle 的同 名函数。

                                Vehicle.__init__(self, speed)       # Vehicle. 函数名”来用它的超方法

                                self.fuel = fuel          #我们又给Car 增加了一个fuel 属性,并且在 drive 中多输出一行信息

 

                def drive(self, distance):

 Vehicle.drive(self,distance)

                                print 'need %f fuels'% (distance * self.fuel)

 

 b = Bike(15.0)

 c = Car(80.0,0.012)

 b.drive(100.0)

 drive(100.0)

 

解释一下代码 __init__ 函数会在建的候自动调用,用来初始化它的参数,要在提供。于是我提供一个数来初始化speed 

class 定义后面的括号里表示这个类继承于哪个类。Bike(Vehicle) 就是说 Bike 是继承自Vehicle 中的子类。 Vehicle 中的属性和方法,Bike 都会有。因为 Bike 不需要有额外的功 能,所以用 pass 在类中保留空块,什么都不用写。

Car 类中,我们又重新定义了__init__ 和 drive 函数,这样会覆盖掉它继承自Vehicle 的同 名函数。但我们依然可以通过“Vehicle. 函数名”来调用它的超类方法。 以此来获得它作为Vehicle 所具有的功能。注意,因为是通过类名调用方法,而不是像之前一样通过对象来调 用,所以这里必须提供self 的参数值。在调用超类的方法之后,我们又给Car 增加了一个

fuel 属性,并且在 drive 中多输出一行信息。

最后,我们分别创建一个速度为15 的自行车对象,和一个速度为 80、耗油量为0.012 的汽 车,然后让它们去行驶100 的距离

 

 

 

 

29、andor 技巧

 

看下面这段代码:

 a ="heaven"

 b ="hell"

 c = True and a orb

 print c

 

 d = False and a orb

 print d

输出:

heaven

hell

结果很奇怪是不是? 表达式从左往右运算,1 和"heaven" 做 and 的结果是"heaven" ,再与 "hell" 做or 的结果是 "heaven" ;0和"heaven" 做 and 的结果是0,再与 "hell" 做 or 的结果是"hell" 。 抛开绕人的and 和 or 的逻辑,你只需记住,在一个bool and a or b 语句中,当 bool 条件 为真时,结果是a;当 bool 条件为假时,结果是b。 有学过 c/c++ 的同学应该会发现,这和bool?a:b 表达式很像。

有了它,原本需要一个 if-else 语句表述的逻辑:

if a > 0:

print "big"

 else:

 print "small"

就可以直接写成:

 print (a > 0) and "big" or "small"

 

然而不幸的是如果直接么用,有一天你会到坑的。 和 c 语言中的 ?: 表达式不同, 这里 的and or 语句是利用了 python 中的逻辑运算实现的。 a 本身是个假(如0""果就不会像你期望的那

比如:

a = ""

b = "hell"

 c = True and a orb

 print c

得到的结果就是"hell" 。因为 "" 和"hell"做 and 的结果是"hell" 。

所以,and-or 真正的技巧在于, 确保 a 不会。 最常用的方式是使a 成为 [a] 、 b 成为[ b ] ,然后使用返回值列表的第一个元素:

a = ""

 b = "hell"

 c = (True and [a] or [b])[0]

 print c

由于 [a] 是一个非空列表,所以它决不会假。即使 a  0 或者 '' 或者其它假,列表 [a] 真,因它有一个元素。

在两个常量值进行选择时,and-or 会让你的代码更简单。但如果你觉得这个技巧带来的副 作用已经让你头大了,没关系,用if-else 可以做相同的事情。不过在 python 的某些情况 下,你可能没法使用 if 语句,比如lambda 函数中,这时候你可能就需要 and-or 的帮助了。

 

30、元组

上一次pygame的课中有这样一行代码:

 x, y =pygame.mouse.get_pos()

复制代码 这个函数返回的其实是一个“元组”,今天我们来讲讲这个东西。

元组( tuple )也是一种序列,和我们用了很多次的 list 类似,只是元组中的元素在创建之后就不能被修改。

如:

postion = (1, 2)

 geeks = ('Sheldon','Leonard', 'Rajesh', 'Howard')

复制代码 都是元组的实例。它有和list 同样的索引、切片、遍历等操作

print postion[0]

 for g in geeks:

 print g

 print geeks[1:3]

复制代码 其实我们之前一直在用元组,就是在print 语句中:

print '%s is %d years old' % ('Mike', 23)

 ('Mike', 23) 就是一个元组。这是元组最常见的用处。

再来看一下元组作为函数返回值的例子:

def get_pos(n):

return (n/2, n*2)

得到这个函数的返回值有两种形式,一种是根据返回值元组中元素的个数提供变量

x, y = get_pos(50)

 print x

print y

这就是我们在开头那句代码中使用的方式。

还有一种方法是用一个变量记录返回的元组:

pos = get_pos(50)

print pos[0]

print pos[1]

 

 

31、数学运算

在用计算机编程解决问题的过程中,数学运算是很常用的。python 自带了一些基本的数学 运算方法

python 的数学运算模块叫做 math,再用之前,你需要

import math

math 包里有两个常量:

math.pi

圆周率 π:3.141592...

math.e 自然常数: 2.718281...

数值运算:

math.ceil(x) 对 x 向上取整,比如 x=1.2,返回2

math.floor(x) 对 x 向下取整,比如 x=1.2,返回1

math.pow(x,y) 指数运算,得到 x 的y 次方

math.log(x) 对数,默认基底为e。可以使用第二个参数,来改变对数的基底。比如 math.log(100, 10)

math.sqrt(x) 平方根

math.fabs(x) 绝对值

三角函数 :

math.sin(x)

math.cos(x)

math.tan(x)

math.asin(x)

math.acos(x)

math.atan(x) 注意:这里的 x 是以弧度为单位,所以计算角度的话,需要先换算

角度和弧度互换 :

math.degrees(x) 弧度转角度

math.radians(x) 角度转弧度

 

32、真值表

逻辑判断是编程中极为常用的知识。之前的课我们已经说过,见第6 课和第 11 课。但鉴于 逻辑运算的重要性,今天我再把常用的运算结果总结一下,供大家参考。

这种被称为 “真值表 ”的东西,罗列了基本逻辑运算的结果。你不一定要全背下来,但应该对 运算的规律有所了解。

了便于看清,我用 <=>来表示等价关系。 <=>表示逻辑表达式, <=>表示它的果。

NOT

not False <=> True

not True <=> False (not的结果与原值相反)

OR

True or False <=> True

True or True <=> True

False or True <=> True

False or False <=> False (只要有一个值为True,or 的结果就是True)

AND

True and False <=> False

True and True <=> True

False and True <=> False

False and False <=> False (只要有一个值为False,or 的结果就是False)

NOT OR

not (True or False) <=> False

not (True or True) <=> False

not (False or True) <=> False

not (False or False) <=> True

NOT AND

not (True and False) <=> True

not (True and True) <=> False

not (False and True) <=> True

not (False and False) <=> True

!=

1 != 0 <=> True

1 != 1 <=> False

0 != 1 <=> True

0 != 0 <=> False

==

1 == 0 <=> False

1 == 1 <=> True

0 == 1 <=> False

0 == 0 <=> True

以上就是基本的逻辑运算, 你会在编程中反复用到它们。 就算刚开始搞不清也没关系, 多写 几段代码就会熟悉了

 

33、正则表达式

什么是正则表达式?在回答这个问题之前,先来看看为什么要有正则表达式。

在编程处理文本的过程中,经常会需要按照某种规则去查找一些特定的字符串。 比如知道一个网页上的图片都是叫做'image/8554278135.jpg' 之类的名字,只 是那串数字不一样; 又或者在一堆人员电子档案中, 你要把他们的电话号码全部 找出来,整理成通 讯录。诸如此类工作,如果手工去做,当量大的时候那简直 就是悲剧。但你知道这些字符信息有一定的规律, 可不可以利用这些规律, 让程 序自动来做这些无聊的事 情?答案是肯定的。这时候,你就需要一种描述律的方法,正表达式就是干事的。

表达式就是记录文本规则的代

所以正则表达式并不是python 中特有的功能,它是一种通用的方法python 的正表达式,所做的事情是利用正表达式来搜索文本。要使用它, 你必 须会自己用正则表达式来描述文本规则,我们就从正则表达式的基本 规则开始说起。

1). 首先一种最简单的正表达式,它没有特殊的符号,只有基本的字母或数字的字符

来看如下的一段文字: Hi, I am Shirley Hilton. I amhis wife.

如果我们用“ hi ”这个正则表达式去匹配这段文字, 将会得到两个结果。 因为是 完全匹配,所以每个结果都是“hi ”。这两个“ hi ”分别来自“Shirley ”和 “his ”。情况下正表达式是格区分大小写的,所以“Hi”和“Hilton ” 中的“Hi”被忽略了。

为了验证正则表达式匹配的结果,你可以用以下这段代码做实验:

 

import re

 text = "Hi, Iam Shirley Hilton. I am his wife."

m = re.findall(r"hi", text)

 if m:

 print m

 else:

print 'not match'

 

暂时先不解释这其中代码的具体含义,你只要去更改text 和 findall 中的字符 串,就可以用它来检测正则表达式的实际效果。

2). 如果我们只想找到“hi ”这个单词, 而不把包含它的单词也算在内, 那就可以使用“ b个正表达式。 在以前的字符串处理中, 我们已经见过类似“n” 这种特殊字符。在正则表达式中,这种字符更多,以后足以让你眼花缭乱。

 b”在正表达式中表示单词的开尾,空格、点、行都算是单词分割。而“b”自身又不会匹配任何字符, 它代表的只是一个位置。 所以单词前 后的空格标点之类不会出现在结果里。

在前面那个例子里, “b”匹配不到任何结果。 但“bhi ”的话就可以匹配 到1 个“hi ”,出自“his ”。用这种方法,你可以找出一段话中所有单词“Hi”, 想一下要怎么写。

3). 最后再说一下[] 这个符号。在正表达式中, [] 表示足括号中任一字符。 比如 “[hi]”,它就不是匹配“ hi ”了,而是匹配“ h”或者“i ”。

在前面例子中,如果把正则表达式改为“[Hh]i ”,就可以既匹配“ Hi”,又匹 配“hi”了。

 

 

 

 

 

 

解释下上面代码意思:

r"hi"

这里字符串前面加了 r, raw 的意思它表示字符串不转义。为什么要加这个?你 可以试试 print "\bhi"  r"\bhi" 的区

>>> print"\bhi"

hi

>>> printr"\bhi"

\bhi

可以看到, 不加r 的话,\b 就没有了 python 的字符串碰到“”就会转义它后面的字符。如果你想在字符串里打“”,要打

>>> print"\\bhi"

\bhi

这样的话,我们的正则表达式里就会多出很多 “”,让本来就已经复杂的字符串混乱得像五 仁月饼一般。但加上了 “r”,就表示不要去转义字符串中的任何字符,保持它的原样。

 

re.findall(r"hi", text)

re  python 里的正表达式模 findall 是其中一个方法,用来按照提供的正表达式,去匹配文本中的所有符合条件的字符串。返回果是一个包含所有匹配的 list

 

主要说两个符号 “. ” 和“*”,顺带说下 “S” 和“?” 。 在正表达式中表示除行符以外的任意字符。在提供的那段例子文本中: Hi, I amShirley Hilton. I am his wife.

如果我们用 “i. ”去匹配,就会得到

['i,', 'ir', 'il', 'is', 'if']

你若是暴力一点,也可以直接用 “.”去匹配,看看会得到什么。

与“. ”类似的一个符号是 S”,它表示的是不是空白符的任意字符。注意是大写字符 S

 

在很多搜索中, 会用 “?”表示任意一个字符, “*”表示任意数量连续字符, 这种被称为通配符。 但在正表达式中,任意字符是用”表示,而*不是表示字符,而是表示数量:它表示前面的字符可以重复任意多次(包括 0 次),只要这样的条件,都会被表达式匹配上。

结合前面的 “.*” ,用“I.*e ”去匹配,想一下会得到什么结果?

['I am Shirley Hilton. I am his wife']

是不是跟你想的有些不一样?也许你会以为是

['I am Shirle', 'I am his wife']

这是因为 “*”在匹配时,会匹配尽可能长的结果。如果你想他匹配到最短的就停止,需要用“.*? 。如“I.*?e ”,就会得到第二种果。种匹配方式被称为懒惰匹配,而原本尽可能的方式被称为贪婪匹配。

 

 

匹配手机号,其实就是找出一串连续的数字。更进一步,是11 位,以 1 开头的 数字。

还记得正则第1 讲里提到的 []符号吗?它表示其中任意一个字符。所以要匹配数 字,我们可以用

[0123456789]

由于它连续的字符,有一种化的写法: [0-9]似的 [a-zA-Z] 的用法

有另一种表示数字的方法:

\d

要表示任意长度的数字,就可以用

[0-9]*

或者

\d*

但要注意的是, *表示的任意长度包括0,也就是没有数字的空字符也会被匹配 出来。一个与*类似的符号 +,表示的 1 个或更

所以要匹配出所有的数字串,应当用

[0-9]+

或者

\d+

如果要限定度,就用{}代替+,大括号里写上你想要的。 比如 11 位的数字:

\d{11}

想要再把第一位限定 1,就在前面加上1,后面去掉一位:

1\d{10}

OK. 总结一下提到的符号:

[0-9]

\d

+

{}

现在你可以去一个混杂着各种数据的文件里, 抓出里面的手机号, 或是其他你感 兴趣的数字了

 

 

1). 我们已经了解了正则表达式中的一些特殊符号,如\b 、\d 、. 、\S 等等。这些具 有特殊意义的专用字符被称作“元字符”。常用的元字符还有:

\w - 匹配字母或数字或下划线或汉字(我试验下了,发现3.x 版本可以匹配汉 字,但2.x 版本不可以) \s - 匹配任意的空白符 ^ - 匹配字符串的开始$ - 匹配字符串的结束

2). \S 其实就是\s 的反义,任意不是空白符的字符。同理,还有:

\W - 匹配任意不是字母,数字,下划线,汉字的字符\D - 匹配任意非数字的字符 \B - 匹配不是单词开头或结束的位置

[a] 的反义是 [^a] ,表示除a 以外的任意字符。 [^abcd] 就是除 abcd 以外的任意 字符。

3). 之前我们用过*、+、{} 来表示字符的重复。其他重复的方式还有:

? - 重复零次或一次 {n,} - 重复n 次或更多次 {n,m} - 重复 n 到 m次

正则表达式不只是用来从一大段文字中抓取信息, 很多时候也被用来判断输入的 文本是否符合规范,或进行分类。来点例子看看:^\w{4,12}$ 这个表示一段 4 到 12 位的字符,包括字母或数字或下划线或汉字,可以用来作 为用户注册时检测用户名的规则。(但汉字在python2.x 里面可能会有问题)

\d{15,18} 表示 15 到 18 位的数字,可以用来检测身份证号码

^1\d*[x]? 以 1 开头的一串数字,数字结尾有字母x,也可以没有。有的话就带上 x。

另外再说一下之前提到的转义字符 。如果我们确实要匹配. 或者*字符本身,而 不是要它们所代表的元字符,那就需要用\. 或\* 。 本身也需要用 。 比如"\d+\.\d+"可以匹配出 123.456 这样的结果

 

 

 

 

一个可以匹配出所有结果的表达式是

\(?0\d{2,3}[) -]?\d{7,8}

解释一下:

\(?

()在正则表达式里也有着特殊的含义,所以要匹配字符 "(",需要用 "\("?表示个括号是可有可无的

0\d{2,3}

区号, 0xx或者 0xxx

[) -]?

在区号之后跟着的可能是 ")"" ""-",也可能什么也没有。

\d{7,8}

 8 位的电话

可是,这个表达式虽然能匹配出所有正确的数据 (一般情况下,这样已经足够), 但理论上也会匹配到错误的数据。因为()应当是成对出现的,表达式中对于左右 两个括号并没有做关联处理,例如(02188776543 这样的数据也是符合条件的。

我们可以用正则表达式中的 “| ”符号解决这种问题。 “| ” 相当于python 中“or”的作用, 它连接的两个表达式,只要满足其中之一,就会被算作匹配成功。

于是我们可以把 ()的情况单独分离出来:

\(0\d{2,3}\)\d{7,8}

其他情况:

0\d{2,3}[ -]?\d{7,8}

合并:

\(0\d{2,3}\)\d{7,8}|0\d{2,3}[ -]?\d{7,8}

使用“| ”时,要特别提醒注意的是不同条件之间的顺序。匹配时,会按照从左往右 的顺序,一旦匹配成功就停止验证后面的规则。 假设要匹配的电话号码还有可能 是任意长度的数字(如一些特殊的服务号码),你应该把

|\d+

这个条件加在表达式的最后。 如果放在最前面, 某些数据就可能会被优先匹配为 这一条件。你可以写个测试用例体会一下两种结果的不同。

 

34、随机数

random 模块的作用是产生随机数。之前的小游戏中用到过random 中的 randint :

import random

num = random.randint(1,100)

random.randint(a, b) 可以生成一个 a 到b 间的随机整数,包括 a 和 b。 a、b都必须是整数,且必须 b≥a。当等于的时候,比如:

random.randint(3, 3) 的结果就永远是3

除了 randint,random模块中比较常用的方法还有:

random.random() 生成一个 0 到 1 之间的随机浮点数,包括0 但不包括 1,也就是 [0.0, 1.0)。

random.uniform(a, b) 生成 a、b之间的随机浮点数。不过与randint 不同的是, a、b 无需是整数,也不用考虑大 小。

random.uniform(1.5, 3)

random.uniform(3, 1.5) 这两种参数都是可行的。random.uniform(1.5, 1.5) 永远得到 1.5。

random.choice(seq) 从序列中随机取一个元素。seq 需要是一个序列,比如 list、元组、字符串。

random.choice([1, 2, 3, 5, 8, 13]) #listrandom.choice('hello') # 字符串 random.choice(['hello', 'world']) # 字符串组成的list random.choice((1, 2, 3)) # 元组 都是可行的用法。

random.randrange(start, stop,step) 生成一个从start  stop(不包括 stop), step 的一个随机数。 start、stop、step都要 为整数,且start<stop 。 比如:

random.randrange(1, 9, 2) 就是从[1, 3, 5, 7]中随机选取一个。 start 和step 都可以不提供参数,默认是从 0 开始,间隔为1。但如果需要指定 step,则必 须指定 start。

random.randrange(4) #[0, 1, 2, 3]

random.randrange(1, 4) #[1, 2, 3] random.randrange(start,stop, step) 其实在效果上等同于 random.choice(range(start,stop, step))

random.sample(population, k) 从population 序列中,随机获取 k 个元素,生成一个新序列。 sample 不改变原来序列。

random.shuffle(x)

把序列 x 中的元素顺序打乱。shuffle 直接改变原有的序列。

以上是 random 中常见的几个方法。如果你在程序中需要其中某一个方法,也可以这样写:

from random import randint

randint(1, 10)

另外,有些编程基础的同学可能知道,在随机数中有个seed 的概念,需要一个真实的随机 数,比如此刻的时间、鼠标的位置等等,以此为基础产生伪随机数。在python 中,默认用 系统时间作为seed。你也可以手动调用 random.seed(x) 来指定seed。





文献参考:

整理自:

python 基础教程至60课

https://wenku.baidu.com/view/001ef117e009581b6ad9eb52.html?re=view