zoukankan      html  css  js  c++  java
  • python:类4——魔法方法(定制序列、迭代)、生成器、推导式

    一、定制序列(容器类型)

    http://bbs.fishc.com/forum.php?mod=viewthread&tid=48793&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403:容器类型

    • 协议(Protocols)与其他编程语言中的接口很相似,它规定你哪些方法必须要定义。然而,在Python中的协议就显得不那么正式。事实上,在Python中,协议更像是一种指南。
    • 定制容器的协议
      • 如果你希望定制的容器是不可变的话,你只需要定义__len__()和__getitem__()方法                                       (str、tuple)
      • 如果你希望定制的容器是可变的话,你需要定义_len__()、__getitem__()、__setitem__()和__delitem__()方法        (list)
      • 例:编写一个不可变的自定义列表,要求记录列表中每个元素被访问的次数
      •   1 class CountList():
          2     def __init__(self, *args):
          3         self.l = [x for x in args]
          4         self.count = {}.fromkeys(range(len(self.l)), 0)
          5             
          6     def __len__(self):
          7         return len(self.l)
          8         
          9     def __getitem__(self, index):
         10         self.count[index] += 1
         11         return self.l[index]

    二、迭代

    • 定义:迭代就类似循环,每一次重复的过程称为一次迭代的过程,每一次迭代的结果将作为下一次迭代的初始值
    • 提供迭代方法的容器称为迭代器,如:list,字符串,字典
    • 通常用for i in “xx”,用于触发迭代操作;while循环实现for

    • iter()——容器对象调用iter()就得到它的迭代器
    • next()——调用next()迭代其就会返回下一个值,如果没有值可以返回了python就会抛出一个叫做StopIteration
    • In [105]: s = "fichc"
      
      In [106]: it = iter(s)
      
      In [107]: next(it)
      Out[107]: 'f'
      
      In [108]: next(it)
      Out[108]: 'i'
    • __iter__()——返回迭代器本身(对应iter()方法)
    • __next__()——决定迭代器的规则(对应next()方法)
    • Fibs数列(下一个值是前两个的和):
      1 class Fibs():
      2     def __init__(self, a, b):
      3         self.a = a
      4         self.b = b
      5     def __iter__(self):
      6         return self
      7     def __next__(self):
      8         self.a, self.b = self.b, self.a + self.b
      9         return self.a
    
    In [128]: a = test.Fibs(1, 2)
    
    In [129]: it = iter(a)
    
    In [130]: next(it)
    Out[130]: 2
    
    In [131]: next(it)
    Out[131]: 3
    
    In [121]: a = test.Fibs(1, 2)
    
    In [122]: for each in a:
         ...:     if each < 20:    #也可以把判断放到__next__(self),通过if xxx: raise StopIteration
         ...:         print(each)
         ...:     else:
         ...:         break
         ...:     
    2
    3
    5
    8
    13

    三、乱入:生成器generator

    • 迭代器和生成器是python引入的最强大的概念
    • 生成器是迭代器的一种实现,因为定义生成器需要写个类,生成器只需要一个yield
    • 生成器的发明使得python模仿协同程序的概念得以实现。协同程序就是可以运行的独立函数调用,函数可以暂停或者挂起,并在需要的时候从程序离开的地方继续或者重新开始
    • 像一个会暂停,又能回来的return
    • 可以使用next()一次执行一回,也可以用for循环一次去不打印
    •   1 #coding:utf8
        2 def myGen():
        3     print('生成器被执行')
        4     yield 1
        5     yield 2
      
      In [137]: myG = test.myGen()
      In [138]: next(myG)
      生成器被执行
      Out[138]: 1                   #在yield1暂停
      In [139]: next(myG)
      Out[139]: 2                   #在yield暂停
      In [140]: next(myG)
      ---------------------------------------------------------------------------
      StopIteration                             Traceback (most recent call last)
      <ipython-input-140-bf2e9b04d728> in <module>()
      ----> 1 next(myG)
      StopIteration: 

      斐波那契数列也可以用到yield
      def libs():
      a = 0
      b = 1
      while True:
      a, b = b, a + b
      yield a
    • 列表推倒式 
    • a = [i for i in range(100) if not (i % 2) and i % 3]
      [2, 4, 8, 10, 14, 16, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52, 56, 58, 62, 64, 68, 70, 74, 76, 80, 82, 86, 88, 92, 94, 98]
    • python3还有字典推导式

    • b = {i:i % 2 == 0 for i in range(10)}
      {0: True, 1: False, 2: True, 3: False, 4: True, 5: False, 6: True, 7: False, 8: True, 9: False}
    • 集合set推导式
    • In [154]: {i for i in [1,2,1,3]}
      Out[154]: {1, 2, 3}
    • 生成器推导式,可以next(e),作为函数的参数时,可以省略最外边的括号。
    • In [156]: e = (i for i in range(10))
      Out[156]: <generator object <genexpr> at 0x7fa1635bb518>

       生成器推到式若果作为函数的参数,可以直接写推导式,不用写圆括号;也可以加上

    • >>> sum(i for i in range(100) if i %2)
      2500
    • 没有元组推导式,元组推导式其实得到的就是生成器推导式;没有字符串推导式
  • 相关阅读:
    973. K Closest Points to Origin
    919. Complete Binary Tree Inserter
    993. Cousins in Binary Tree
    20. Valid Parentheses
    141. Linked List Cycle
    912. Sort an Array
    各种排序方法总结
    509. Fibonacci Number
    374. Guess Number Higher or Lower
    238. Product of Array Except Self java solutions
  • 原文地址:https://www.cnblogs.com/daduryi/p/6737186.html
Copyright © 2011-2022 走看看