码迷,mamicode.com
首页 > 其他好文 > 详细

四:迭代器生成器

时间:2019-09-20 20:51:14      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:for循环   hid   next   sel   获取   大小   error:   raise   函数调用   

一:迭代器

暂时不涉及到自定义迭代器,涉及到了再补,暂时知道for循环的原理就可以了.

1有__iter__就是可迭代的,也叫可迭代协议

2双下方法:c语言写好了的内置方法,可以用不止一种的方式调用

3迭代取值的工具
4可迭代对象执行__iter__得到的返回值就是迭代器.
5可以把它看作数据流,只能前进不能后退,迭代到头了就会从内存消失
6如果还有__next__方法,那么就是迭代器了,光有__next__就什么都不是
7迭代器的另一个好处是节省内存,不会一次全在内存中生成,而是随着循环每次生成一个
8只关心当前数据,和下一个数据的位置,其他数据没有在内存当中
9迭代器一定是可迭代的
10很少自己写迭代器,都是用for去循环可迭代对象,当到头没有数据报StopIteration异常,for循环完美的处理了这个异常.
11.for循环的本质就是通过__iter__拿到迭代器,然后不断调用__next__获取数值,直到报异常并处理掉
迭代器更多的是从已经存在的数据结构中获取值,就算没有索引也可以不断获取后面的数据,迭代器知道这些就可以了.
迭代器几乎不会自己定义
技术图片
class Test:
    pass
test = Test()
for i in test:
    print(i)
#TypeError: ‘Test‘ object is not iterable
for遍历不可迭代对象报错
技术图片
class Test:
    def __iter__(self):
        return self

test = Test()
for i in test:
    print(i)
#TypeError: iter() returned non-iterator of type ‘Test‘
for遍历可迭代对象,但不是迭代器报错
技术图片
class MyStudents:
    """
    自定义一个迭代器对象
    """
    stu_list = []

    def __init__(self, *args):
        names = args
        self.position = 0
        for name in names:
            self.stu_list.append(name)
    
    #对象本身就是迭代器,返回自身
    def __iter__(self):
        return self

    def __next__(self):
        if self.position < len(self.stu_list):
            item = self.stu_list[self.position]
            self.position+=1
            return item
        else:
            raise StopIteration()

    def __str__(self):
        return self.stu_list.__str__()

    def add_student(self,stu_name):
        self.stu_list.append(stu_name)

stus = MyStudents("张三","李四")
stus.add_student("王五")
stus.add_student("赵六")
print(stus)
for i in stus:
    print(i)
自定义迭代器

二:生成器本质是迭代器

优点:不会一下子在内存中生成全部数据,调用一次__next__才生成一个数据
生成器保存的是生成数据的逻辑,而非具体数据,调用一次生成一次数据
生成器更多的是不断的根据外界条件来生成不同的值到内存中
1生成器表达式:相同的生成数据的逻辑,后面说
2生成器函数:含有yield的函数就是生成器函数,且根据不同的条件生成不同的数据
技术图片
1 def gen_test():
2     for i in range(20):
3         yield "test%s" % i
简单生成器

生成器函数调用了只会生成一个generator对象,不会执行里面的代码

只有next(g)才会执行到第一个yield结束,并将值返回

正好for循环就可以不断的调用next()

三:表达式

列表推导式:一次性生成全部数据

技术图片
li=[i**2 for i in range(10)]
print(li)
View Code

for遍历每个元素,按照开头的规则生成每个元素,for的简写形式

多层嵌套
技术图片
names = [[Tom, Billy, Jefferson, Andrew, Wesley, Steven, Joe],
         [Alice, Jill, Ana, Wendy, Jennifer, Sherry, Eva]]
#先for的外面的大列表,然后for里面的小列表
#推导式的缺点是无法打断点,debug
ret = [li for name in names for li in name if li.count("e")>=2]
print(ret)
View Code

生成器表达式:不会全部数据一次性生成到内存中

只把列表生成式外层中括号换成小括号即可

字典推导式:原理还是for循环遍历的是key

技术图片
合并大小写对应的value值,将k统一成小写
mcase2 = {a: 10, b: 34, A: 7, Z: 3}
ret2 = {k.lower():mcase2.get(k.lower(),0)+mcase2.get(k.upper(),0) for k in mcase2}
print(ret2)
View Code

集合推导式

技术图片
集合推倒式,和列表推到式就差一个{},多了去重的功能
squared = {x**2 for x in [1, -1, 2]}
print(squared)
View Code

 

四:迭代器生成器

标签:for循环   hid   next   sel   获取   大小   error:   raise   函数调用   

原文地址:https://www.cnblogs.com/gyxpy/p/11559613.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!