python中的迭代器和生成器

迭代器协议:
把一个类作为一个迭代器使用需要在类中实现两个方法__iter__()与__next__()
iter() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next()
方法并通过 StopIteration 异常标识迭代的完成。

Python的__getitem__(self,n)方法为拦截索引运算
当实例s出现s[i]这样的索引运算时,Python会调用这个实例s继承的__getitem__(self,n)方法,并把s作为第一个参数传递(self),将方括号内的索引值 i 传递给第二个参数 n

my_iterator.py

#!usr/bin/python
# -*- coding:utf8 -*-
class MyNumbers(object):
    def __iter__(self):
        self.a = 1
        print("__iter__被调用了")
        return self

    # def __getitem__(self, item):
    #     print("__getitem__被调用了")
    #     if item <= 20:
    #         return item
    #     else:
    #         raise StopIteration

    def __next__(self):
        print("__next__被调用了")
        if self.a <= 20:
            x = self.a
            self.a += 1
            return x
        else:
            raise StopIteration


my_class = MyNumbers()
# for x in my_class:
#     print(x)
my_iter = iter(my_class)
for x in my_iter:
    print(x)

通过测试可以发现,如果for循环中要遍历的对象有__iter__方法,则会先调用__iter__方法,返回迭代器对象,然后调用__next__获取值,如果没有, 则会调用__getitem__方法


可迭代协议:
可以被for循环的就是可迭代的,目前有字符串,列表,元组,字典,集合
可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义非常简单,就是内部实现了__iter__方法。
但是我在官网英文手册中看到可以是实现了__iter__或__getitem__方法的类的对象,这就很迷。

iterable_protocol.py

#!usr/bin/python
# -*- coding:utf8 -*-
from collections import Iterable, Sequence

string = "hello"
l = [1, 2, 3, 4]
t = tuple(l)
d = {1: 2, 3: 4}
s = set(l)

for each in [string, l, t, d, s]:
    print(isinstance(each, Iterable))
    # python中的序列类型有字符串,列表,元组
    print(isinstance(each, Sequence))

生成器
python中的生成器可以是: 1. 生成器推导式 2. 函数中有yield
生成器的作用: 1. 节省内存 2. python协程的实现是基于生成器,当然你也可以使用oython3.5的async/await和gevent这种更加新颖的

举例 fibonacci数列

#!usr/bin/python
# -*- coding:utf8 -*-
print(type((i * 2 for i in range(5))))  # 生成器推导式


def fibonacci(num):
    a, b = 0, 1
    current_index = 0
    while current_index < num:
        result = a
        a, b = b, a + b
        current_index += 1
        yield result


fib = fibonacci(10)
for value in fib:
    print(value)

读取大文本文件input.txt, 文本中用{|}分割

I have a dream that my four little children {|}will one day live in a nation where they will not be judged by the color of their skin but by the content of their character. I have a dream today.
I have a dream that one day down in Alabama, with {|}its vicious racists, . . . one day right there in Alabama little black boys and black girls will be able to join hands with little white boys and white girls as sisters and brothers. I have a dream today.
I have a dream that one day {|}every valley shall be exalted, every hill and mountain shall be made low, the rough places will be made plain, and the crooked places will be made straight, and the glory of the Lord shall be revealed, and all flesh shall see it together.
This is our hope. . . With this faith we will be able to hew out of the {|}mountain of despair a stone of hope. With this faith we will be able to transform the jangling discords of our nation into a beautiful symphony of brotherhood. With this faith we will be able to work together, to pray together, to struggle together, to go to jail together, to stand up for freedom together, knowing that we will be free one day. . . .
And when this happens, and when we {|}allow freedom ring, when we let it ring from every villa

read_big_file.py

#!usr/bin/python
# -*- coding:utf8 -*-


def myreadlines(f, newline):
    buf = ""
    while True:
        while newline in buf:
            pos = buf.index(newline)
            yield buf[:pos]
            buf = buf[pos + len(newline):]
        chunk = f.read(4096 * 10)
        if not chunk:
            # 说明已经读到了文件结尾, 将剩余yield出去
            yield buf
            break
        buf += chunk


with open("input.txt") as f:
    for line in myreadlines(f, "{|}"):
        print(line)

你可能感兴趣的:(Python)