• python基础之迭代与解析


    先简单看一下文件迭代器

    >>> f=open('file1')
    >>> f.readline()
    "'aaa','bbb','ccc'
    "
    >>> f.readline()
    'asdfasdf
    '
    >>> f.readline()
    'asdfasdf
    '
    >>> f.readline()
    'asdfasdf
    '
    View Code

     现在,有和个next()方法,差不多有同样的效果,每次调用时,返回文件中的下一行。

    >>> f.seek(0)
    0
    >>> next(f)
    "'aaa','bbb','ccc'
    "
    >>> next(f)
    'asdfasdf
    '
    >>> next(f)
    'asdfasdf
    '
    >>> next(f)
    'asdfasdf
    '
    View Code

    这个接口就是python中所谓的迭代协议,有__next__方法的对象会前进到下一个结果(上面的next()方法其实就是调用的__next__()),而在结果的末尾时,则会引发StopIteration。

    在python中,任何对象都认为是可迭代的。任何这类对象都能被for循环或其他迭代工具遍历,因为所有的迭代工具内部工作起来都是在调用 __next__(),并捕捉StopIteration异常离开。

    而列表和很多其他内置对象,不是自身的迭代器,所以不能直接用next()方法,必须调用iter启动迭代。

    >>> L = [1,2,3,4]
    >>> next(L)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'list' object is not an iterator
    >>> I = iter(L)
    >>> next(I)
    1
    >>> next(I)
    2
    >>> next(I)
    3
    View Code

    列表解析入门

    在之前,遍历列表的时候,可以使用for循环,但是现在,可以用列表解析,需要更少的代码,并且运行的更快。

    >>> L=[1,2,3,4]
    >>> for i in range(len(L)):
    ...  L[i]+=10
    ... 
    >>> L
    [11, 12, 13, 14]
    >>> 
    >>> L = [x+10 for x in L]
    >>> L
    [21, 22, 23, 24]
    View Code

    列表解析写在一个方括号中,因为它最终是构建一个新的列表的一种方式。它以一个任意的表达式开始(在上面的例子中是x+1),后面跟着for循环部分,声明了循环变量以及一个可迭代对象(for x in L)

    运行列表解析时,python解释器在内部执行一个L的迭代,按顺序将元素赋值给x,并对各元素运行左边的表达式,将结果收集起来,形成新的列表。

    扩展列表解析语法

    在列表解析中还可以加上if判断

    >>> L
    [21, 22, 23, 24]
    >>> 
    >>> I = [x for x in L if x%2==0 ]
    >>> I
    [22, 24]
    View Code

    在上面的代码中,只留下能被2整除的元素。

    生成器函数

    一般来说,生成器函数和常规函数一样,但是使用yield语句,一次返回一个结果,在每个结果之间挂起和继续它们的状态。当它创建时,自动实现迭代协议。生成器也可以有return语句,用来终止生成器。

    >>> def func(N):
    ...  for i in range(N):
    ...   yield i
    ... 
    >>> type(func)
    <class 'function'>
    >>> f = func(10)
    >>> f
    <generator object func at 0x7f9c112b3c60>
    >>> next(f)
    0
    >>> next(f)
    1
    >>> next(f)
    2
    View Code

    send方法

    >>> def func(N):
    ...  for i in range(N):
    ...   r = yield i
    ...   print(r)
    ... 
    >>> f = func(10)
    >>> f.__next__()
    0
    >>> f.send(10)
    10
    1
    >>> f.send(20)
    20
    2
    >>> f.__next__()
    None
    3
    View Code

    通过send方法发送一个值给生成器,它会先执行后面的代码,然后恢复生成器的代码,并且生成器返回了send的值。如果在生成器结束之前调用 next()方法,yield返回None。

    生成器表达式

    它类似于上面的列表解析,不同的是,它一次返回一个结果,而不是一次返回整个列表

    >>> G = (x for x in "spam")
    >>> G
    <generator object <genexpr> at 0x7f9c112b3d80>
    >>> next(G)
    's'
    >>> next(G)
    'p'
    >>> next(G)
    'a'
    >>> next(G)
    'm'
    >>> next(G)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    View Code

    通过上面的代码可以看出,生成器表达式和列表解析的创建方式几乎一样,只是中括号换成了小括号。

     

  • 相关阅读:
    .net常用框架总结
    微信小程序 语音转换
    nginx+redis实现session共享 .NET分布式架构
    Redis 安装及注册服务
    WebApi跨域
    Uri各个属性取值测试
    一些常用的FFMPEG命令集合
    动态规划重学习笔记
    给自己的电脑时间进行精准校时
    [NOI题库][POJ2536][匈牙利算法][二分图最大匹配]Gopher II
  • 原文地址:https://www.cnblogs.com/baitutu/p/6254271.html
Copyright © 2020-2023  润新知