• 中文
    • 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
    • 757
    • 请登录之后再进行评论

      登录

      赞助本站

      • 支付宝
      • 微信
      • QQ

      感谢一直支持本站的所有人!

      单栏布局 侧栏位置: