zoukankan      html  css  js  c++  java
  • Python基础笔记:高级特性:切片、迭代、列表生成式、生成器、迭代器

    题记:

    在python中,代码不是越多越好,而是越少越好。代码不是越复杂越好,而是越简单越好。

    1行代码能实现的功能,绝不写5行代码。

    请始终牢记:代码越少,开发效率越高。

    切片

    >>> L=list(range(11)) #生成数0~10
    >>> L
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>> L[:5] #输出0~4
    [0, 1, 2, 3, 4]
    >>> L[-5:] #输出倒数第5个~最后
    [6, 7, 8, 9, 10]
    >>> L[3:7] #输出3~6
    [3, 4, 5, 6]
    >>> L[0:6:2] #在0~5,每隔2个取一个
    [0, 2, 4]
    >>> L[::5] #在整个list L上,每隔5个取一个
    [0, 5, 10]

    编写程序:实现一个trim()函数,取出字符串首尾的空格

    def trim(x):
        l=len(x)
        a=0
        b=0
        for i in range(l):
            if x[i]!=' ':
                a=i
                break
        if a==l-1:
            return
        else:
            for i in range(l):
                if x[l-i-1]!=' ':
                    b=l-i
                    break
    def trim(x):  #递归函数实现
        if x[0]==' ':
            x=trim(x[1:])
        if x[-1]==' ':
            x=trim(x[:-2])
        return x
    
    >>> from hello import trim
    >>> trim('hello      ')
    'hello'

    迭代(Iterate)

    可以迭代的有str,list,tuple,dict ;  迭代是通过for...in来完成的

    怎么判断一个对象是否是可迭代对象呢?

    >>> from collections import Iterable
    >>> isinstance('abc',Iterable)
    True
    >>> isinstance([1,2,3],Iterable)
    True
    >>> isinstance(123,Iterable)
    False

    一些迭代示例:

    >>> d={'a':1,'b':2,'c':3} #对dict进行迭代
    >>> for key in d: #迭代键值
    ...     print(key)
    ...
    a
    b
    c
    >>> for v in d.values(): 
    ...     print(v)
    ...
    1
    2
    3
    >>> for key,v in d.items(): #迭代list里元素
    ...     print(key,v)
    ...
    a 1
    b 2
    c 3
    
    for ch in 'ABC': #对str迭代
    ...     print(ch)
    ...
    A
    B
    C
    
    >>> for i,value in enumerate(['A','B','C']): #把list变成索引-元素对
    ...     print(i,value)
    ...
    0 A
    1 B
    2 C
    >>> for i in enumerate(['A','B','C']):
    ...     print(i)
    ...
    (0, 'A')
    (1, 'B')
    (2, 'C')
    >>> L=[]
    >>> for i in enumerate(['A','B','C']): 
    ...     L.append(i)
    ...
    >>> L
    [(0, 'A'), (1, 'B'), (2, 'C')]

    编程:使用迭代查找一个list中最小和最大值,并返回一个tuple

    def find_mm(x):
        if len(x)==0:
            return (None,None)
        else:
            a=min(x)
            b=max(x)
            return (a,b)
    
    >>> from hello import find_mm
    >>> x=[7]
    >>> find_mm(x)
    (7, 7)

    列表生成器

    示例:

    >>> [x*x for x in range(1,11)] #生成1*1 2*2 ... 10*10 的列表
    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    >>> [x*x for x in range(1,11) if x%2==0] #仅筛选出偶数的平方
    [4, 16, 36, 64, 100]
    >>> [m+n for m in 'ABC' for n in 'XYZ'] #生成连个串的全排列
    ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
    >>> d={'x':'1','y':'2','z':'3'} #把dict生成列表
    >>> [k+v for k,v in d.items()]
    ['x1', 'y2', 'z3']
    >>> [k+'='+v for k,v in d.items()]
    ['x=1', 'y=2', 'z=3']
    
    C:work>python #在C:work 目录下打开python解释器
    Python 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os #导入os模块
    >>> L=[d for d in os.listdir('.')] #os.listdir可以列出文件和目录
    >>> ss=[s.upper() for s in L] #把list中所有的字符串变成大写
    >>> ss
    ['HELLO.PY', '__PYCACHE__']
    >>> ss=[s.lower() for s in L] #把list中所有的字符串变成小写
    >>> ss
    ['hello.py', '__pycache__']
    >>>
    >>> for i in ss:
    ...     if i=='hello.py':
    ...             print('Right here!')
    ...
    Right here!

    内置函数 isinstance(x,str)、isinstance(x,int) 用来判断x是否是str型或int型

    >>> x=5
    >>> if isinstance(x,int)==True:
    ...     print('yes!')
    ...
    yes!
    >>> x='fuck you!'
    >>> if isinstance(x,str)==True:
    ...     print('yes!')
    ...
    yes!

    上面判断一个数据是否可以迭代也是 isinstance() 这个函数(名);

    练习:修改列表生成式,通过添加 if 语句保证列表生成式能正确地执行

    L1=['Hello','World',18,'Apple',None]

    >>> L1 = ['Hello', 'World', 18, 'Apple', None]
    >>> L2=[s.lower() for s in L1 if isinstance(s,str)==True]
    >>> L2
    ['hello', 'world', 'apple']

    生成器:一边循环一边计算的机制

    迭代器:已经计算完毕,进行循环

    生成器(generator)

    要创建一个generator :只要把一个列表生成式的[ ] 改成 ( ) ,就创建了一个generator:

    >>> g=(x*x for x in range(10))
    >>> g
    <generator object <genexpr> at 0x000001E5405C7830>

    可以用next() 函数一个一个打印出来generator 的下一个返回值;

    >>> g=(x*x for x in range(10))
    >>> g
    <generator object <genexpr> at 0x000001E5405C7830>
    >>> next(g)
    0
    >>> next(g)
    1
    >>> next(g)
    4
    >>> next(g)
    9
    .....
    >>> next(g)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    
    #genereator 保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

    当然,generator是可迭代的:

    >>> isinstance(g,Iterable)
    True
    >>> for i in g:
    ...     print(i)
    ...
    16
    25
    36
    49
    64
    81
    >>>
    #generator g 好像有记忆一项,上次利用next函数输出到9,这次从16开始输出!

    有输出斐波那契数列的函数:

    def fib(max):
        n,a,b=0,0,1
        while n<max:
            print(b)
            a,b=b,a+b
            n+=1
        return 'done'

    把这个函数换成generator 只需要把 print(b) 改为 yield b 就可以了。

    def fib(max):
        n,a,b=0,0,1
        while n<max:
            yield b
            a,b=b,a+b
            n+=1
        return 'done'
    a = f() #创建生成器对象
    
    for i in range(10): #斐波那契数列中前10个元素 
        print(a.__next__(), end=' ') 
    
    1 1 2 3 5 8 13 21 34 55
    

      

    >>> from hello import fib
    >>> f=fib(5)
    >>> for i in f:
    ...     print(i)
    ...
    1
    1
    2
    3
    5
    #如果是函数的话:
    >>> f=fib(6)
    1
    1
    2
    3
    5
    8

    但是用for 循环调用generator 时,发现拿不到generator 的return 语句的返回值。如果想要拿到返回值,必须不过StopIteration 错误,返回值包含在StopIteration 的 value 中:

    >>> from hello import fib
    >>> g=fib(6)
    >>> while True:
    ...     try:
    ...             x=next(g)
    ...             print('g:',x)
    ...     except StopIteration as e:
    ...             print('Generator return value:',e.value)
    ...             break
    ...
    g: 1
    g: 1
    g: 2
    g: 3
    g: 5
    g: 8
    Generator return value: done

    编程:输出杨辉三角

    def triangle(max):
        n,L=0,[1]
        for i in range(max):
            yield L
            s=[]
            if len(L)>=2:
                for j in range(len(L)-1):
                    s.append(L[j]+L[j+1])
            s.append(1)
            s.insert(0,1)
            L=s
        return 'done'
    >>> t=triangle(10)
    >>> while True:
    ...     try:
    ...             x=next(t)
    ...             print('t:',x)
    ...     except StopIteration as e:
    ...             print('Generator return value:',e.value)
    ...             break
    ...
    t: [1]
    t: [1, 1]
    t: [1, 2, 1]
    t: [1, 3, 3, 1]
    t: [1, 4, 6, 4, 1]
    t: [1, 5, 10, 10, 5, 1]
    t: [1, 6, 15, 20, 15, 6, 1]
    t: [1, 7, 21, 35, 35, 21, 7, 1]
    t: [1, 8, 28, 56, 70, 56, 28, 8, 1]
    t: [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
    Generator return value: done

    迭代器

    直接作用于 for 循环的数据类型有:

    1.集合数据类型,如list、tuple、dict、set、str等;

    2.generator ,包括生成器和带yield 的generator function。

    可以被next() 函数调用并不断返回下一个值的对象称为迭代器:Iterator

    >>> from collections import Iterable 
    >>> isinstance([], Iterable) #使用isinstance()#判断一个对象是否是Iterable对象
    True
    >>> isinstance((x for x in range(10)), Iterator) #判断一个对象是否是Iterator对象
    True

    你可能会问,为什么listdictstr等数据类型不是Iterator

    这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

    Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

    凡是可作用于for循环的对象都是Iterable类型;

    凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

    集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

  • 相关阅读:
    tomcat控制台运行窗口中文乱码
    jquery html5 file 上传图片显示图片
    修改输入框placeholder文字默认颜色-webkit-input-placeholder
    H5移动端知识点总结
    PostgreSQL
    PostgreSQL
    Hexo系列(2)
    SQL
    Java笔记-序列化的注意点
    js、css外部文件的相对路径问题
  • 原文地址:https://www.cnblogs.com/jiaxinwei/p/8317976.html
Copyright © 2011-2022 走看看