首页 >> 新闻 >> 科技 >> 前沿科技 >> 正文
  • 传智播客郑州校区Python学习之迭代器与生成器

  • 时间:2018-01-17 新闻来源: 北京热线
    •  一、传智播客Python学习:文件操作的“b模式”(补充)

        像rbwbab这种模式,是以字节的形式操作,需要注意以下几个问题:

        1)文件不能保存在内存中,只能保存在硬盘中,以二进制的形式,Python只能将字符串写入文本文件,要将数值数据存储到文本文件中,必须先使用函数str()将其转化为字符串格式。

      2)在以rb .rw等编码打开文件的时候,不能定义编码类型,即不能在open()函数内指定encoding。再补充一些文件操作的方法,具体如下:

      复制代码

      with open("尼古拉斯赵四","wb") as f:

      f.encoding() #文件的打开编码,encoding=“”定义的是哪个编码方式,输出的就是哪个编码方式,与源文件的编码方式无关

      #如果不知道源文件编码,可以在定义时将encoding=latin-1”,该编码方式兼容大部分编码

      #f.flush() #刷新,当对文件进行修改操作的时候,通过此方法可以使更改生效(pycharm不需要此方法的原因是pycharm内部机制会自动保存)

      #f.tell() #打印光标所在的位置,光标移动 是以字节为单位,read()是以字符为单位,中文3个字节,英文一个字节

      #with open("尼古拉斯赵四","w",encoding="utf-8",newline="") as f: 读取源文件中真正的换行符,

                                                通过readlines方法读取文件,不加newline=“”的话输出\n,加上是\r\n

      #f.seek(0) #指定光标的位置,在0

      # f.seek(10,0) #后面的是默认位置,即光标位置从0开始,以b的方式操作,因为seek是以字节为单位移动光标

      # f.seek(10,1) #1代表的相对位置

      # f.seek(3,1) #基于10移动光标

      # f.seek(-5 ,2) #2代表倒序指定光标位置

      # f.truncate(10) #从开头截取到10 (光标位置) w\w+模式下不行

      复制代码

       

      二、传智播客Python学习:文件路径

        如果程序文件存放在当前路径下,那么通过open("文件名称")的方式就可以打开文件,但如果程序文件存放在其他路径下或或当前文件的子目录下,那么就必须要提供文件路径,它让Python到系统中的特定位置去找。

        相对路径

      假如:在当前路径下有一个files文件,files文件下有一个“尼古拉斯赵四”这个程序文件,我如果想要打开这个文件,就需要使用相对文件路径来打开它。

      with open("files\尼古拉斯赵四",encoding="utf-8") as f:

          print(f.readlines())

       

      这行代码让Python去打开文件夹files下的“尼古拉斯赵四”这个文件,在Windows系统中,文件路径使用反斜杠(\)而不是斜杠(/

      绝对路径

      可以将文件在计算机中的准确位置告诉Python,这样就不用关心当前运行的程序存储在什么地方,这称为绝对路径。当相对路径行不通时,可以使用绝对路径。绝对路径通常比相对路径更长,在Linux系统中类似于这样:/home/dir/files/1.txt;在Windows系统中类似于这样:C:\Users\dir\files\1.txt

      通过使用绝对路径,可读取系统中的任何地方的文件。

       

      三、传智播客Python学习:迭代器

      迭代器和递归函数的区别:递归函数是不断的重复调用自己,必须有一个明确的条件,而且每进行更深一层的循环,规模一定要较之前要小,迭代器,每次循环都要依赖于上一次的结果。

      迭代器协议:对象必须提供一个_next_()方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常(只能往后走不能往前退)。

      可迭代对象:实现了迭代协议的对象(如何实现?对象内部定义一个_iter_()方法)。

      协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,summinmax函数等)使用迭代器协议访问对象。

      for循环举例:for循环就遵循迭代器协议来循环所有的对象,(列表、字典、字符串、元组,集合)这些其实都不是可迭代对象,只不过在for循环时,调用了他们内部的_iter_方法,把他们变成了可迭代对象,然后for循环调用可迭代对象,然后就可以调用_next_()方法,直至异常结束,用代码解释如下:

      name=[1,2,3]for i in name:         l=name.__iter__()   print(l.__next__())    print(i)

       

      for循环列表的时候,实质上是调用了列表的内置方法_iter_(),将列表变成一个可迭代对象,成为可迭代对象后,该列表就有了_next_()方法,在调用此方法一个一个读取。

      还有一个next()方法,其实质就是在调用_next_()函数。

      可以被next()函数调用并不断返回值下一个值的对象就是迭代器:Iterator,列表,字典这些基本数据类型虽然是可迭代对象,但不是迭代器,可以通过_iter_()方法将它们变为迭代器。

      name=[1,2,3]

      print(type(name.__iter__()))           通过_iter_方法将可迭代对象变为迭代器

      运行结果:

       

      四、传智播客Python学习:列表生成式和三元运算

      如果现在需求是输出从1-9的数字,当然大部分人首先会想到for循环,如下:

      复制代码

      name=[]

      for i in range(10):

      name.append(i)

      print(name)

      运行结果:

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

      复制代码

       

      如果用一行写出来,如下:

       

      print([i for i in range(10)])     

      运行结果:

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

       

      那什么是三元运算呢?

       

      name="尼古拉斯赵四"

      print("会街舞" if name=="尼古拉斯赵四" else "不会街舞")        一元:“会街舞”  二元:通过if语句判断   三元:“不会街舞”

      输出结果:

      会街舞

       

      其实很好理解,if前面可以理解为判断为True的返回结果,else后是判断为False的返回结果,这就是三元运算。

      三元运算还可以与列表生成式结合使用,需求:输出10以内大于5的数字

      print([i for i in range(10) if i>5  ])

      运行结果:

      [6, 7, 8, 9]

       

      但注意一点,在这种语句,就不能在家else了,一定要注意三元,加上了else就变成四元了,程序会报错的

       

      五、传智播客Python学习:生成器

        在Python中,一边循环一边计算的机制,称为生成器(generator)。生成器可以理解为一种数据类型,这种数据类型自动实现的迭代器协议(其他的数据类型是通过调用自己的内置方法_iter_方法),所以生成器就是可迭代对象,直接就可以使用_next_()方法。

        生成器分类在python中的表现形式(python有两种不同的方式提供生成器)

        1.生成器表达式,生成器其实就是把列表生成器的[]变为()。即上面的列表生成式,我要将它变为生成器的话:

      print(type((i for i in range(10) if i>5  )))

      运行结果:

       

      generator保存的是算法,每次调用next(),就计算出下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

      复制代码

      a=(i for i in range(10) if i>5 )

      print(a.__next__)

      print(next(a))              每次执行一次next()操作,只会读取一个值

      print(next(a))

      运行结果:

      6

      7

      复制代码

      如果这个生成器有N多个值呢?一直用next()显然是不方便的,所以一般都是用for循环。

       

        2.函数生成式

      只要在定义函数的时候,把return()变为yield()就可以了,yield()保存上一次读取值的位置,当再次调用时,就从该位置开始调用。普通函数遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

      复制代码

      def func():

      yield 1

      yield 2

      res=func()

      print(res.__next__())

      运行结果:

      1

      复制代码

       

      执行一次_next_()方法,输出1,程序停留在此位置,当再次执行一次_next_()方法时,会从1的位置开始执行,再输出2,这就是函数生成式。当执行_next_()读取完全部元素后,再次执行程序就会抛出StopIteration异常,处理异常的方法会在后面的文章中详细介绍。

      网站首页 | 关于我们 | 联系方式 | 招聘信息 | 版权声明 | 网站地图 | 北京热线
      地址:北京市海淀区永泰园14号楼 投稿QQ:1914290061 投稿邮箱:bjrenews@126.com
      Copyright © 2010 www.bjrxnews.com Inc. All Rights Reserved. 北京热线 版权所有