• 💡 Python是脚本语言,代码越少,开发效率越高

    切片

  • tuple不可变,但tuple也可以用切片操作,只是操作的结果仍是tuple

  • 字符串'xxx'也可以用切片操作,只是操作结果仍是字符串
  • 只写[:]就可以原样复制一个list

    迭代

  • Python的for循环不仅可以用在listtuple上,还可以作用于其他可迭代对象上

  • 只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代
    • for key in dfor value in d.values()for k, v in d.items()
  • 如何判断对象可迭代,通过collections.abc模块的Iterable类型判断

    1. from collections.abc import Iterable
    2. isinstance('HHT', Iterable) #True
  • Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身

    1. for i, value in enumerate(['A', 'B', 'C']):
    2. print(i, value)
    3. #0 A
    4. #1 B
    5. #2 C

    列表生成式

  • [x * x for x in range(1,11) if x % 2 == 0]

  • [m + n for m in 'ABC' for n in 'XYZ']

    1. d = {'x':'A','y':'B','z':'C'}
    2. [k + '=' + v for k, v in d.items()] #['y=B','x=A', 'z=C']
  • [x if x % 2 == 0 else -x for x in range(1, 11)]在一个列表生成式中,for前面的if...else表达式(不带**else**会报错),而for后面的if过滤条件,不能带else

    生成器

  • 生成器一方面是不必创建完整的list从而节省大量空间,另一方面是可以按照某种算法推算出来后续的元素

  • 只要把一个列表生成式的[]改成()就创建了一个generator,如g = (x * x for x in range(10)),可以通过next()函数获得generator的下一个返回值
    • 每次调用next(g)就计算出g的下一个元素值,直到没有更多元素时抛出StopIteration的错误
  • 如果一个函数的定义中包含yield关键字,那么这是一个generator函数,调用一个generator函数将返回一个generator对象

    1. def fib(max):
    2. n, a, b = 0, 0, 1
    3. while n < max:
    4. yield b
    5. a,b = b, a + b
    6. n = n + 1
    7. return 'done'
  • 每次调用next()时执行,遇到yield语句返回,再次执行时从上次返回的yield语句出继续执行

  • 💡 调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator
  • 把函数改成generator函数后,一般不会使用next()来获取下一个值,而是直接使用for循环来迭代

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

    迭代器

  • 可以直接作用于for循环的数据类型有,统称为可迭代对象Iterable

    • 集合数据类型:listtupledictsetstr
    • generator,包括生成器和带yield的generator function
  • 可被next()函数调用并不断返回下一个值的对象成为迭代器:Iterator
  • 生成器都是Iterator对象,但listdictstr虽然是Iterable,但不是Iterator
    • 因此把listdictstrIterable变成Iterator可以使用iter()函数
  • Python的Iterator对象表示的是一个数据流,可以看作是有序序列,但不能提前知道序列长度,其计算是惰性的,只有需要返回下一个数据时它才会计算
    • Python的for循环本质上就是通过不断调用next()函数实现的