• 中文
    • English
  • 注册
  • 查看作者
  • 第十一章:高级特性

    一. 切片

    对list或者tuple取指定索引范围的元素,可以通过切片操作

    1. 取前n个元素:L[0:n]

    L = ['A','B','C','D','E']
    
    print(L[0:3])  # ['A', 'B', 'C']

    2. 如果第一个索引是0,还可以省略:L[:n]

    L = ['A','B','C','D','E']
    
    print(L[:3])  # ['A', 'B', 'C']

    3. 倒数切片:L[:-n]

    L = ['A','B','C','D','E']
    
    print(L[-3])  # C
    print(L[:-3])  # ['A', 'B']
    print(L[-3:])  # ['C', 'D', 'E']

    4. 前n个数,每m取一个:L[:n:m]

    L = list(range(100))
    
    print(L[:10]) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    print(L[:10:2]) # [0, 2, 4, 6, 8]

    5. 所有数,每m个取一个:L[::m]

    L = list(range(50))
    
    print(L[::5]) # [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]

    6. 复制一个list:L[:]

    L = ['A','B','C','D','E']
    M = L[:]
    print(M) # ['A', 'B', 'C', 'D', 'E']
    L[2] = '1'
    print(L) # ['A', 'B', '1', 'D', 'E']
    print(M) # ['A', 'B', 'C', 'D', 'E']

    7. 取n~m范围内的数:L[n:m+1]

    L = list(range(50))
    n = 10
    m = 20
    print(L[n:m]) #[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
    print(L[n:m+1]) # [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

    8. 切片操作tuple(因为tuple不可变,所以结果仍是tuple)

    L = ('A','B','C','D','E')
    print(L[:3]) # ('A', 'B', 'C')

    9. 切片操作字符串

    L = ['A','B','C','D','E']

    10. 利用切片操作,实现一个trim()函数,去除字符串首尾的空格

    s = '  ZHANG  JIA  '
    def trim(s):
        while s[:1] == " ":
            s = s[1:]
    
        while s[-1:] == " ":
            s = s[:-1]
        return s
    
    print(trim(s)) #ZHANG  JIA

    二. 迭代

    如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration),在Python中,迭代是通过for … in来完成的。只要是可迭代对象,无论有无下标,都可以迭代。

    1. 迭代list

    L = [1,2,3]
    for i in L :
        print(i)
    
    '''
    输出
    1
    2
    3
    '''

    2. 迭代tuple

    T = (1,2,3)
    for i in T :
        print(i)
    
    '''
    输出
    1
    2
    3
    '''

    3. 迭代dict的key

    d = {'a': 1, 'b': 2, 'c': 3}
    for i in d :
        print(i)
    
    '''
    输出
    a
    b
    c
    '''

    4. 迭代dict的value

    d = {'a': 1, 'b': 2, 'c': 3}
    for i in d.values():
        print(i)
    
    '''
    输出
    1
    2
    3
    '''

    5. 迭代dict的key和value

    d = {'a': 1, 'b': 2, 'c': 3}
    for i,j in d.items():
        print(i,j)
    
    '''
    输出
    a 1
    b 2
    c 3
    '''

    6. 迭代字符串

    s = 'JIA'
    for i in s:
        print(i)
    
    '''
    输出
    J
    I
    A
    '''

    7. 判断是否是可迭代对象

    from collections.abc import Iterable
    tof = isinstance('abc',Iterable)
    print(tof) # True

    8. enumerate函数可以把一个list变成索引-元素对,即可获取索引 

    L = ['A','B','C']
    for i, j in enumerate(L):
        print(i,j)
    
    '''
    输出
    0 A
    1 B
    2 C
    '''

    三. 列表生成式

    列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

    1.  生成list[n~m]

    L = list(range(0,10))
    print(L) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    2.  生成[1×1, 2×2, 3×3, …, 10×10]

    L = [x * x for x in range(0,10)]
    print(L) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

    3. for循环后面还可以加上if判断

    L = [x * x for x in range(0,10) if x % 2 == 1]
    print(L) # [1, 9, 25, 49, 81]

    4. 使用两层循环,可以生成全排列:

    L = [m + n for m in 'ABC' for n in 'DEF'] 
    print(L) # ['AD', 'AE', 'AF', 'BD', 'BE', 'BF', 'CD', 'CE', 'CF']

    5. 列出当前目录下的所有文件和目录名(当前目录下的二级目录获取不到),可以通过一行代码实现:

    import os
    L  = [d for d in os.listdir(".")]
    print(L)

    6. 列表生成式也可以使用两个变量来生成list:

    d = {'x': 'A', 'y': 'B', 'z': 'C' }
    print([k + "=" + v for k,v in d.items()])  # ['x=A', 'y=B', 'z=C']

    7. 在一个列表生成式中,for前面的if … else是表达式,必须加else,而for后面的if是过滤条件,不能带else,也就是说,for前面的if else用于改变x的值,for后面的if用于筛选哪些x值

    print([x if x % 2 == 0 else -x for x in range(1, 11)]) # [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
    print([x for x in range(1, 11)]) #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    四. 生成器

    如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

    1. 创建generator方法一:把一个列表生成式的[]改成(),就创建了一个generator

    L = [x * x for x in range(0,10)]
    G = (x * x for x in range(0,10))
    print(L) #[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    print(G) #<generator object <genexpr> at 0x0000022CA767DC10>

    2. 直接输出G并不能获取对应的值,因为generator保存的是算法,需要通过next()函数获得generator的下一个返回值,如果没有更多的元素时,系统会抛出StopIteration错误

    G = (x * x for x in range(0,4))
    print(next(G)) # 0
    print(next(G)) # 1
    print(next(G)) # 4
    print(next(G)) # 9
    print(next(G)) # 报错:Traceback (most recent call last):

    3. next()很少用到,一般使用for循环迭代generator

    G = (x * x for x in range(0,4))
    for i in G:
        print(i)
    
    '''
    0
    1
    4
    9
    '''

    4. 创建generator方法二:如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator

    # 普通函数
    
    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            print(b)
            a, b = b, a + b  #相当于: t = (b, a + b)   a = t[0]   b = t[1] ,但不必显式写出临时变量t就可以赋值,t是一个tuple
            n = n + 1
        return 'done'
    
    print(fib(6)) # 1 1 2 3 5 8 done
    
    # generator
    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b  #相当于: t = (b, a + b)   a = t[0]   b = t[1] ,但不必显式写出临时变量t就可以赋值,t是一个tuple
            n = n + 1
        return 'done'
    
    print(fib(6)) # <generator object fib at 0x000002A2639ADC10>

    5. 函数和generator的区别:函数是顺序执行,遇到return语句或者最后一行函数语句就返回,而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

    def add():
        print("step 1")
        yield 1
        print("step 2")
        yield 2
        print("step 3")
        yield 3
    print(next(add())) # step 1  1
    print(next(add())) # step 1  1
    o = add()
    print(next(o)) # step 1  1
    print(next(o)) # step 2  2

    6. for循环或者next()调用generator时,无法获取generator的return语句的返回值

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b  #相当于: t = (b, a + b)   a = t[0]   b = t[1] ,但不必显式写出临时变量t就可以赋值,t是一个tuple
            n = n + 1
        return 'done'
    
    for i in fib(6):
        print(i)
    
    '''
    1
    1
    2
    3
    5
    8 
    没有done这个返回值,因为generator中拿不到return的返回值
    '''

    6. 可以通过捕获StopIteration错误的value来获取return语句的返回值

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b  #相当于: t = (b, a + b)   a = t[0]   b = t[1] ,但不必显式写出临时变量t就可以赋值,t是一个tuple
            n = n + 1
        return 'done'
    
    o = fib(5)
    
    while True:
        try:
            print(next(o))
        except StopIteration as e:
            print(e.value)
            break
    
    '''
    1
    1
    2
    3
    5
    done
    '''

    五. 迭代器

    上面我们说过,可以被for循环的对象啊成为可迭代对象Iterable,而可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

    from collections.abc import Iterator
    L = [1,2,3]
    print(isinstance(L, Iterator)) #False
    print(isinstance(iter(L), Iterator)) #True
    print(iter(L)) #<list_iterator object at 0x000001FAE4B73DF0>
    print(next(iter(L))) #1

    把list、dict、str等Iterable变成Iterator可以使用iter()函数

    参考资料

    [1] 廖雪峰-Python教程

  • 0
  • 0
  • 0
  • 1.2k
  • 请登录之后再进行评论

    登录
    单栏布局 侧栏位置: