py自学总结

FH_Bin 贡献于2017-03-28

作者 bin  创建于2016-08-08 03:32:00   修改者bin  修改于2016-08-12 11:04:00字数20886

文档摘要:
关键词:

 PY自学总结 1、 Print 打印 print(hello) print(1+2+3) 2、 input 输入 print('what is your name?') input() print('nice to meet you') F5运行后,将会等待你的输入。 3、 变量 3.1变量定义 3.1.1变量类型 字符串:表示一串字符,需要用''或""引起来 整数 浮点数:就是小数 bool(布尔):这个比较特殊,是用来表示逻辑“是”“非”的一种类型,它只有两个值,True和False。(注意这里没有引号,有了引号就变成字符串了) print('what is your name?') name=input() print('My name is') print(name) 3.1.2变量的命名规则 l 第一个字符必须是字母或者下划线“_” l 剩下的部分可以是字母、下划线“_”或数字(0-9) l 变量名称是对大小写敏感的,myname和myName不是同一个变量。 l 几个有效的例子: __my_name name_23 a1b2_c3 几个无效的例子: 2things this is spaced out my-name 3.2 bool变量 3.2.1逻辑运算符 >:大于 <:小于 >=:大于等于 <=:小于等于 ==:等于。比较两个值是否相等。之所以用两个等号,是为了和变量赋值区分开来。 !=:不等与 not:逻辑“非”。如果x为True,则not x为False and:逻辑“与”。如果x为True,且y为True,则x and y为True or:逻辑“或”。如果x、y中至少有一个为True,则x or y为True 3.2.2bool变量转换 针对bool('False'),print一下结果,会发现是True。这是什么原因? 因为在python中,以下数值会被认为是False: l 为0的数字,包括0,0.0; l 空字符串,包括'',""; l 表示空值的None; l 空集合,包括(),[],{}; l 其他的值都认为是True。 3.2.3例子 num=10 print('Guess what I think?') answer=int(input()) result = answernum print('too big?') print (result) result = answer==num print('equal?') print (result) 4、 If条件语句 if 条件:选择执行的语句; l 特别说明:条件后面的冒号不能少,同样必须是英文字符。 l 特别特别说明:if内部的语句,需要有一个统一的缩进,一般用4个空格。python用这种方法替代了其他很多编程语言中的{}。你也可以选择1/2/3...个空格或者按一下tab键,但必须整个文件中都统一起来。千万不可以tab和空格混用,不然就会出现各种莫名其妙的错误。所以建议都直接用4个空格。 5、 While循环语句 5.1定义 同if一样,while也是一种控制流语句,另外它也被称作循环语句,程序执行到while处,“当”条件为True时,就去执行while内部的代码,“当”条件为False时,就跳过。 语法为:while 条件:循环执行的语句同if一样,注意冒号,注意缩进。 流程图如下: 5.2例子 num=10 print('Guess what I think?') a=1 while a==1: answer=int(input()) if answernum: print('too big') if answer==num: print('bingo') a=0 print('the game is over') 6、 Random随机 之前我们用了很多次的print和input方法,它们的作用是实现控制台的输入和输出。除此之外,python还提供了很多模块,用来实现各种常见的功能,比如时间处理、科学计算、网络请求、随机数等等等等。今天我就来说说,如何用python自带的随机数模块,给我们的小游戏增加不确定性。 引入模块的方法:from 模块名 import 方法名 看不懂没关系,这东西以后我们会反复用到。今天你只要记住,你想要产生一个随机的整数,就在程序的最开头写上: from random import randint 之后你就可以用randint来产生随机数了。 还记得input后面的()吗,我们使用randint的时候后面也要有()。而且,还要在括号中提供两个数字,先后分别是产生随机整数范围的下限和上限。例如: randint(5, 10),这样将会产生一个5到10之间(包括5和10)的随机整数。 7、 For循环 for ... in ... 同while一样,for循环可以用来重复做一件事情。在某些场景下,它比while更好用。 比如之前的一道习题:输出1到100的和,我们用while来做,需要有一个值来记录已经做了多少次,还需要在while后面判断是不是到了100。 如果用for循环,则可以这么写: a=0 for i in range(0, 101): a=a+i print (a) 解释一下,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。 8、 字符串 8.1 字符串 字符串就是一组字符的序列,它一向是编程中的常见问题。之前我们用过它,以后我们还要不停地用它。 l python中最常用的字符串表示方式是单引号(’’)和双引号("")。我还是要再说:一定得是英文字符! string'和”string”的效果是一样的。 可以直接输出一个字符串print( ‘good’); 也可以用一个变量来保存字符串,然后输出str = ‘bad’ ,print( str); l 如果你想表示一段带有英文单引号或者双引号的文字,那么表示这个字符串的引号就要与内容区别开。 内容带有单引号,就用双引号表示"It's good"; 反之亦然,’You are a "BAD" man’; python中还有一种表示字符串的方法:三个引号(’’’)或者("""); 在三个引号中,你可以方便地使用单引号和双引号,并且可以直接换行: ''' "What's your name?" I asked. "I'm Han Meimei." ''' l 还有一种在字符串中表示引号的方法,就是用\,可以不受引号的限制。 \'表示单引号,\"表示双引号:‘I\'m a \"good\" teacher’; \被称作转译字符,除了用来表示引号,还有比如用: \ \表示字符串中的\; \n表示字符串中的换行; \还有个用处,就是用来在代码中换行,而不影响输出的结果: "this is the\ same line" 这个字符串仍然只有一行,和 "this is thesame line"是一样的,只是在代码中换了行。当你要写一行很长的代码时,这个会派上用场。 8.2格式化字符串1 我们在输出字符串的时候,如果想对输出的内容进行一些整理,比如把几段字符拼接起来,或者把一段字符插入到另一段字符中间,就需要用到字符串的格式化输出。 l 先从简单的开始,如果你想把两段字符连起来输出: str1 = 'good' str2 = 'bye' 你可以: print str1 + str2 或者还可以把字符变量一个字符串相加: print 'very' + str1 print str1 + ' and ' + str2 l 但如果你想要把一个数字加到文字后面输出,比如这样: 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. 注意区分:有引号的表示一段字符,没有引号的就是一个变量,这个变量可能是字符,也可能是数字,但一定要和%所表示的格式相一致。 8.3格式化字符串2 之前我们说到,可以用%来构造一个字符串,比如: 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、 循环嵌套 设想一样,如果我们要输出5个*,用for循环要这么写: for i in range(0, 5):  print( '*') 如果想让这5个*在同一行,就在print语句后面加上end=’’;  for i in range(0,5): print('*',end='') 但如果我想要这样一个图形,怎么办? * * * * * * * * * * * * * * * * * * * * * * * * * 当然,你可以循环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('*',end='')  print(‘’) 注意:第二个print的缩进和内层的for是一样的,这表明它是外层for循环中的语句,每次i的循环中,它会执行一次。 print后面没有写任何东西,是起到换行的作用,这样,每输出5个*,就会换行。 要输出第二个三角图案时,我们需要根据当前外层循环的序数,设置内层循环应当执行的次数。 for i in range(1,6): for i in range(0,i): print('*',end=''); print("") 内层的j每次从0到i进行循环。 这样,当第一次i=0时,j就是range(0,1),只输出1个*。 而当最后一次i=5时,j就是range(0,5),输出5个*。 10、 函数 10.1函数的定义 数学上的函数,是指给定一个输入,就会有唯一输出的一种对应关系。编程语言里的函数跟这个意思差不多,但也有不同。函数就是一块语句,这块语句有个名字,你可以在需要时反复地使用这块语句。它有可能需要输入,有可能会返回输出。 举一个现实中的场景:我们去餐厅吃饭,跟服务员点了菜,过了一会儿,服务员把做好的菜端上来。餐厅的厨房就可以看作是一个函数,我们点的菜单,就是给这个函数的参数;厨师在厨房里做菜的过程就是这个函数的执行过程;做好的菜是返回结果,返回到我们的餐桌上。 我们之前已经用到过python里内建的函数,比如input和range。 以range(1,10)为例,range是这个函数的名称,后面括号里的1和10是range需要的参数。它有返回结果,就是一个从1到9的序列。 再来看input(),括号里面没有,表示我们没有给参数。函数执行过程中,需要我们从控制台输入一个值。函数的返回结果就是我们输入的内容。 PS:range还可以接受1个或3个参数,input也可以接受1个字符串参数。可以等我以后讲,或去查阅相关资料了解详细。 如果我们要自己写一个函数,就需要去 定义 它。python里的关键字叫def(define的缩写),格式如下: def sayHello():    print 'hello world!' sayHello是这个函数的名字,后面的括号里是参数,这里没有,表示不需要参数。但括号和后面的冒号都不能少。下面缩进的代码块就是整个函数的内容,称作函数体。 然后我们去调用这个函数: sayHello() 得到和直接执行print 'hello world!'一样的结果。 10.2函数的参数 前面我们知道了怎样定义一个自己的函数,但我们没有给他提供输入参数的功能。不能指定参数的函数就好比你去餐厅吃饭,服务员告诉你,不能点菜,有啥吃啥。这显然不能满足很多情况。 所以,如果我们希望自己定义的函数里允许调用者提供一些参数,就把这些参数写在括号里,如果有多个参数,用逗号隔开,如: 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。 10.3函数应用实例 前面稍稍介绍了一下函数,但光说概念还是有些抽象了,今天就来把之前那个小游戏用函数改写一下。 我希望有这样一个函数,它比较两个数的大小。 如果第一个数小了,就输出“too small” 如果第一个数大了,就输出“too big” 如果相等,就输出“bingo” 函数还有个返回值,当两数相等的时候返回True,不等就返回False。 于是我们来定义这个函数: def isEqual(num1,num2): if num1num2: print('too big') return False if num1==num2: print('binggo') return True 这里说一下,return是函数的结束语句,return后面的值被作为这个函数的返回值。函数中任何地方的return被执行到的时候,这个函数就会结束。 然后在我们的小游戏里使用这个函数: from random import randint; num=int(randint(1,100)) i=False while i==False: answer=int(input()) i=isEqual(answer,num) print("The game is over") 在isEqual函数内部,会输出answer和num的比较结果,如果相等的话,i会得到返回值True,否则i得到False,循环继续。 11、 If、else、if else语句 今天补充之前讲过的一个语句:if。为什么我跳要着讲,因为我的想法是先讲下最最基本的概念,让你能用起来,之后你熟悉了,再说些细节。 之前说的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 num1num2:        print 'too big'        return False;    else:        print 'bingo'        return True 12、 列表LIST 12.1初识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] 12.2操作LIST 假设我们现在有一个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中尝试。 5. 索引(index)和切片(slice) 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] 12.3点球小游戏1 先说一下方向的设定。我的想法比较简单,就是左中右三个方向,用字符串来表示。射门或者扑救的时候,直接输入方向。所以这里我准备用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...' 12.4点球小游戏 2 昨天有了一次罚球的过程,今天我就让它循环5次,并且记录下得分。先不判断胜负。 用score_you表示你的得分,score_com表示电脑得分。开始都为0,每进一球就加1。 from random import choice score_you = 0 score_com = 0 direction = ['left', 'center', 'right'] for i in range(5):    print '==== Round %d - You Kick! ====' % (i+1)    print 'Choose one side to shoot:'    print 'left, center, right'    you = raw_input()    print 'You kicked ' + you    com = choice(direction)    print 'Computer saved ' + com    if you != com:        print 'Goal!'        score_you += 1    else:        print 'Oops...'    print 'Score: %d(you) - %d(com)\n' % (score_you, score_com)    print '==== Round %d - You Save! ====' % (i+1)    print 'Choose one side to save:'    print 'left, center, right'    you = raw_input()    print 'You saved ' + you    com = choice(direction)    print 'Computer kicked ' + com    if you == com:        print 'Saved!'    else:        print 'Oops...'        score_com += 1    print 'Score: %d(you) - %d(com)\n' % (score_you, score_com) 注意:手机上代码有可能会被换行。 这段代码里有两段相似度很高,想想是不是可以有办法可以用个函数把它们分离出来。 12.5点球小游戏3 在上面代码的基础上,我们加上胜负判断,如果5轮结束之后是平分,就继续踢。 所以我们把一轮的过程单独拿出来作为一个函数kick,在5次循环之后再加上一个while循环。 另外,这里把之前的score_you和score_com合并成了一个score数组。这里的原因是,要让kick函数里用到外部定义的变量,需要使用全局变量的概念。暂时想避免说这个,而用list不存在这个问题。 from random import choice score = [0, 0] direction = ['left', 'center', 'right'] def kick():    print '==== You Kick! ===='    print 'Choose one side to shoot:'    print 'left, center, right'    you = raw_input()    print 'You kicked ' + you    com = choice(direction)    print 'Computer saved ' + com    if you != com:        print 'Goal!'        score[0] += 1    else:        print 'Oops...'    print 'Score: %d(you) - %d(com)\n' % (score[0], score[1])    print '==== You Save! ===='    print 'Choose one side to save:'    print 'left, center, right'    you = raw_input()    print 'You saved ' + you    com = choice(direction)    print 'Computer kicked ' + com    if you == com:        print 'Saved!'    else:        print 'Oops...'        score[1] += 1    print 'Score: %d(you) - %d(com)\n' % (score[0], score[1]) for i in range(1):    print '==== Round %d ====' % (i+1)    kick() while(score[0] == score[1]):    i += 1    print '==== Round %d ====' % (i+1)    kick() if score[0] > score[1]:    print 'You Win!' else:    print 'You Lose.' 12.6字符串的分割 字符串和list之间有很多不得不说的事。比如有同学想要用python去自动抓取某个网页上的下载链接,那就需要对网页的代码进行处理。处理的过程中,免不了要在字符串和list之间进行很多操作。 我们先从最基本的开始。假设你现在拿到了一个英语句子,需要把这个句子中的每一个单词拿出来单独处理。 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。 12.7字符串的索引和切片 之前说了,字符串和list有很多不得不说的事。今天就来说说字符串的一些与list相似的操作。 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方法也可以对字符串使用,作用就是用连接符把字符串中的每个字符重新连接成一个新字符串。不过觉得这个方法有点鸡肋,不知道在什么场景下会用到。 newword = ','.join(word) 13、 文件处理 13.1读文件 之前,我们写的程序绝大多数都依赖于从命令行输入。假如某个程序需要输入很多数据,比如一次考试的全班学生成绩,再这么输就略显痛苦了。一个常见的办法就是把学生的成绩都保存在一个文件中,然后让程序自己从这个文件里取数据。 要读取文件,先得有文件。我们新建个文件,就叫它data.txt。在里面随便写上一些话,保存。把这个文件放在接下来你打算保存代码的文件夹下,这么做是为了方便我们的程序找到它。准备工作就绪,可以来写我们的代码了。 打开一个文件的命令很简单: open('文件名') 这里的文件名可以用文件的完整路径,也可以是相对路径。因为我们把要读取的文件和代码放在了同一个文件夹下,所以只需要写它的文件名就够了。 f = open('data.txt') 但这一步只是打开了一个文件,并没有得到其中的内容。变量f保存了这个 文件,还需要去读取它的内容。你可以通过read()函数把文件内所有内容读进一个字符串中。 data = f.read() 做完对文件的操作之后,记得用close()关闭文件,释放资源。虽然现在这样一个很短的程序,不做这一步也不会影响运行结果。但养成好习惯,可以避免以后发生莫名的错误。 完整程序示例: f = open('data.txt') data = f.read() print data f.close() 读取文件内容的方法还有 readline() #读取一行内容 readlines() #把内容按行读取至一个list中 去替换程序的第二行,看看它们的区别。 13.2写文件 打开文件我们昨天已经讲过。但python默认是以只读模式打开文件。如果想 要写入内容,在打开文件的时候需要指定打开模式为写入: f = open('output.txt', 'w') 'w'就是writing,以这种模式打开文件,原来文件中的内容会被你新写入的内容覆盖掉,如果文件不存在,会自动创建文件。 不加参数时,open为你默认为'r',reading,只读模式,文件必须存在,否则引发异常。 另外还有一种模式是'a',appending。它也是一种写入模式,但你写入的内容不会覆盖之前的内容,而是添加到文件中。 写入内容的方法同样简单: f.write('a string you want to write') write的参数可以是一个字符串,或者一个字符串变量。 示例程序: data = 'I will be in a file.\nSo cool!' out = open('output.txt', 'w') out.write(data) out.close() 在你的程序保存目录下,打开output.txt就会看到结果。 留两道课后作业: 1.从一个文件中读出内容,保存至另一个文件。 d=open('data.txt') data=d.read() f=open('new.txt','w') f.write(data) f.close() d.close() 2.从控制台输入一些内容,保存至一个文件。 a=input() b=open('input.txt','w') b.write(a) b.close() 13.3处理文件中的数据 比如我现在拿到一份文档,里面有某个班级里所有学生的平时作业成绩。因为每个人交作业的次数不一样,所以成绩的数目也不同,没交作业的时候就没有分。我现在需要统计每个学生的平时作业总得分。 记得我小的时候,经常有同学被老师喊去做统计分数这种“苦力”。现在电脑普及了,再这么干就太弱了。用python,几行代码就可以搞定。 看一下我们的文档里的数据: #-- scores.txt 刘备 23 35 44 47 51 关羽 60 77 68 张飞 97 99 89 91 诸葛亮 100 先把文件读进来: f = open('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 = open('result.txt', 'w') output.writelines(results) outpus.close() 大功告成,打开文件检验一下结果吧。 以下是完整程序,把其中print前面的注释符号去掉,可以查看关键步骤的数据状态。不过因为字符编码的问题,list的中文可能会显示为你看不懂的字符。 f = open('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 = open('result.txt', 'w') output.writelines(results) output.close() 以下是自己写的程序: f=open('scores.txt') lines=f.readlines() f.close() o=open('sum.txt','w') o.close() for line in lines: scores=line.split(' ') add=0 for score in scores[1:]: name=scores[0] score=int(score) add=add+score add1=str(add)+'\n' sum=name+add1 print(sum) s=open('sum.txt','a') s.write(sum) s.close() 14、 Break l while循环:在条件不满足时结束 l for循环:遍历完序列后结束。 l 如果在循环条件仍然满足或序列没有遍历完的时候,想要强行跳出循环,就需要用到break语句。 while True:   a = raw_input()  if a == 'EOF':    break 上面的程序不停接受用户输入。当用户输入一行“EOF”时,程序结束。 for i in range(10):   a = raw_input()   if a == 'EOF':    break 上面的程序接受用户10次输入,当用户输入一行“EOF”时,程序提前结束。 回到我们最早的那个猜数字小游戏。用break可以加上一个功能,当用户输入负数时,游戏就结束。如此一来,假如有玩家猜了几次之后仍然猜不中,一怒之下想要直接退出游戏,就猜一个负数。 添加的代码是: if answer < 0:  print 'Exit game...'  break 15、 continue break是彻底地跳出循环,而continue只是略过本次循环的余下内容,直接进入下一次循环。 在我们前面写的那个统计分数的程序里,如果发现有成绩不足60分,就不记入总成绩。当然,你可以用if判断来实现这个效果。但我们今天要说另一种方法:continue。 for score in data[1:]:  point = int(score)  if point < 60:   continue  sum += point 注意:无论是continue还是break,其改变的仅仅是当前所处的最内层循环的运行,如果外层还有循环,并不会因此略过或跳出。 在脑中模拟运行下面这段程序,想想会输出什么结果。再敲到代码里验证一下: i = 0 while i < 5:  i += 1  for j in range(3):   print j   if j == 2:    break  for k in range(3):   if k == 2:    continue   print k  if i > 3:   break  print i 16、 异常处理 在程序运行时,如果我们的代码引发了错误,python就会中断程序,并且输出错误提示。 比如我们写了一句: print int('0.5') 运行后程序得到错误提示: Traceback (most recent call last): File "C:/Python27/test.py", line 1, in 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中的语句处理异常。于是输出了“File not exists.”。如果文件被顺利打开,则会输出“File opened!”,而不会去执行except中的语句。 但无论如何,整个程序不会中断,最后的“Done”都会被输出。 在try...except语句中,try中引发的异常就像是扔出了一只飞盘,而except就是一只灵敏的狗,总能准确地接住飞盘。 17、 字典dictionary 今天介绍一个python中的基本类型--字典(dictionary)。 字典这种数据结构有点像我们平常用的通讯录,有一个名字和这个名字对应的信息。在字典中,名字叫做“键”,对应的内容信息叫做“值”。字典就是一个键/值对的集合。 它的基本格式是(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 = {} 18、 模块 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 19、 用文件保存游戏1 到目前为止,python最入门的语法我们都已经有所涉及,相信大家一路学过来,多少也能写出一些小程序。在接下来的课程中,我会基于实例来更深入地介绍python 现在,我要在最早我们开发的那个猜数字游戏的基础上,增加保存成绩的功能。用到的方法就是前几课讲过的文件读写。今天是第一部分。 在动手写代码前,先想清楚我们要解决什么问题,打算怎么去解决。你可以选择根据每次游戏算出一个得分,记录累计的得分。也可以让每次猜错都扣xx分,猜对之后再加xx分,记录当前分数。而我现在打算记录下我玩了多少次,最快猜出来的轮数,以及平均每次猜对用的轮数。 于是,我要在文件中记录3个数字,如: 3 5 31 它们分别是:总游戏次数,最快猜出的轮数,和猜过的总轮数(这里我选择记录总轮数,然后每次再算出平均轮数) 接下来可以往代码里加功能了,首先是读取成绩。新建好一个game.txt,里面写上: 0 0 0 作为程序的初始数据。 用之前的方法,读入文件: f = open('e:\py\game.txt') score = f.read().split() 这里,我用了open方法,它和file()的效果一样。另外,我还用了绝对路径。当你写这个程序时,记得用你自己电脑上的路径。 为便于理解,把数据读进来后,分别存在3个变量中。 game_times = int(score[0]) min_times = int(score[1]) total_times = int(score[2]) 平均轮数根据总轮数和游戏次数相除得到: avg_times = float(total_times) / game_times 注意两点: 1.我在total_times前加上了float,把它转成了浮点数类型再进行除法运算。如果不这样做,两个整数相除的结果会默认为整数,而且不是四舍五入。 2.因为0是不能作为除数的,所以这里还需要加上判断: if game_times > 0:   avg_times = float(total_times) / game_times else:   avg_times = 0 然后,在让玩家开始猜数字前,输出他之前的成绩信息: print '你已经玩了%d次,最少%d轮猜出答案,平均%.2f轮猜出答案' % (game_times, min_times, avg_times) %.2f这样的写法我们以前也用过,作用是保留两位小数。 好了,运行程序看一下效果: 你已经玩了0次,最少0轮猜出答案,平均0轮猜出答案 由于还没有做保存功能,我们手动去文件里改一下成绩看运行效果。(其实有些小游戏就可以用类似的方法作弊) 下面,我们要把真实的游戏数据保存到文件中。 20、 用文件保存游戏2 我们已经能从文件中读取游戏成绩数据了,接下来就要考虑,怎么把我们每次游戏的结果保存进去。 首先,我们需要有一个变量来记录每次游戏所用的轮数: times = 0 然后在游戏每进行一轮的时候,累加这个变量: times += 1 当游戏结束后,我们要把这个变量的值,也就是本次游戏的数据,添加到我 们的记录中。 如果是第一次玩,或者本次的轮数比最小轮数还少,就记录本次成绩为最小 轮数: if game_times == 0 or times < min_times:   min_times = times 把本次轮数加到游戏总轮数里: total_times += times 把游戏次数加1: game_times += 1 现在有了我们需要的数据,把它们拼成我们需要存储的格式: result = '%d %d %d' % (game_times, min_times, total_times) 写入到文件中: f = open('e:\py\game.txt', 'w') f.write(result) f.close() 按照类似的方法,你也可以记录一些其他的数据,比如设定一种记分规则作为游戏得分。虽然在这个小游戏里,记录成绩并没有太大的乐趣,但通过文件来记录数据的方法,以后会在很多程序中派上用场。 21、 用文件保存游戏3 你的小游戏现在已经可以保存成绩了,但只有一组成绩,不管谁来玩,都会算在里面。所以今天我还要加上一个更多的功能:存储多组成绩。玩家需要做的就是,在游戏开始前,输入自己的名字。而我会根据这个名字记录他的成绩。这个功能所用到的内容我们几乎都说过,现在要把它们结合起来。 首先要输入名字,这是我们用来区分玩家成绩的依据: name = raw_input('请输入你的名字:') 接下来,我们读取文件。与之前不同,我们用readlines把每组成绩分开来: lines = f.readlines() 再用一个字典来记录所有的成绩: scores = {} for l in lines:  s = l.split()  scores[s[0]] = s[1:] 这个字典中,每一项的key是玩家的名字,value是一个由剩下的数据组成的数组。这里每一个value就相当于我们之前的成绩数据。 我们要找到当前玩家的数据: score = scores.get(name) 字典类的get方法是按照给定key寻找对应项,如果不存在这样的key,就返回空值 None。 所以如果没有找到该玩家的数据,说明他是一个新玩家,我们给他初始化一组成绩: if score is None:  score = [0, 0, 0] 这是我们拿到的score,已经和上一课中的score一样了,因此剩下的很多代码都不用改动。 当游戏结束,记录成绩的时候,和之前的方法不一样。我们不能直接把 这次成绩存到文件里,那样就会覆盖掉别人的成绩。必须先把成绩更新到scores字典中,再统一写回文件中。 把成绩更新到scores中,如果没有这一项,会自动生成新条目: scores[name] = [str(game_times), str(min_times), str(total_times)] 对于每一项成绩,我们要将其格式化: result = '' for n in scores:   line = n + ' ' + ' '.join(scores[n]) + '\n'   result += line 把scores中的每一项按照“名字 游戏次数 最低轮数 总轮数\n”的格式拼成字符串,再全部放到result里,就得到了我们要保存的结果。 最后就和之前一样,把result保存到文件中。

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档