迭代器和生成器

一、迭代器

1、什么是迭代器

迭代器是一个重复取值的工具,且每一次的取值都是基于上一代的结果,相当于一个更新换代的过程。

2、迭代器的作用

迭代器提供了一种不依赖索引取值的方法。

3、可迭代对象

内置有方法的都叫做可迭代对象

4、迭代器对象

内置有和方法的都叫做迭代器对象

可以用dir()查看内置方法

5、迭代器的使用

字符串和容器数据类型的数据都是可迭代对象,当可迭代对象调用方法时可以编程一个迭代器,取值时调用方法即可一个一个取值,当值取完后若继续取值,将会报错,取值的过程时要一个取一个。

PS:迭代器对象无论执行多少次iter方法得到的还是迭代器对象本身。

l = [1,2,3,4]

# 生成一个迭代器对象
iter_l = l.__iter__()

# 迭代器取值 调用__next__
print(iter_l.__next__())  # 1
print(iter_l.__next__())  # 2
print(iter_l.__next__())  # 3
print(iter_l.__next__())  # 4
print(iter_l.__next__())  # 如果取完了 直接报错

二、for循环的本质

1、for循环的本质

for循环内部执行的步骤:1.将in后面的对象调用转换成迭代器对象

2.调用方法取值

3.内部有异常

2、迭代取值的特点

从for循环的本质可以看出,迭代取值可以不依赖于素引取值,内存中永远只有for循环取得一条数据,不会导致内存溢出,但同时也有不能够获取指定值的元素、取完后会报StopIteration的错误。

三、生成器

1、什么是生成器

本质是迭代器,是用户自定义的迭代器

2、生成器的形式

生成器在不调用的时候是函数,内部的返回值用yield返回。

3、生成器的使用

自定义的生成器在不调用的时候是函数,调用后是生成器,生成器的值的获取需要通过调用内部的方法,每调用一次通过yield返回一个值,此时迭代器的函数没用停止运行,而是暂停在yield处,等待下一次的方法获取返回值。若没有调用则停止运行。

def func():
    print('first')
    yield  666  # 函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行
    print('second')
    yield  777
    print('third')
    yield  888
    print('forth')
    yield
    yield
    
# # yield后面跟的值就是调用迭代器__next__方法你能得到的值
# # yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回
g = func()  # 生成器初始化:将函数变成迭代器

# 当只调用一次时,func函数先打印执行,先打印“first”,获取到迭代器g的一个值,停止运行
print(g.__next__())  # 'first'  666

# 当调用两次的时候,第一次去之后停在yield,继续运行,进行第二次的值的获取
print(g.__next__())  # 'second'  777

yield可以通过调用send()方法接收外部的值,通过调用send()方法,给yield左边的变量传值,然后执行方法。

def dog(name):
    print('%s 准备开吃'%name)
    while True:
        food = yield
        print('%s 吃了 %s'%(name,food))

        
g = dog('egon')
print(g.__next__()) # 必须先将代码运行至yield 才能够为其传值
print(g.send('狗不理包子'))  # 给yield左边的变量传参  触发了__next__方法

# egon 准备开吃
# egon 吃了 狗不理包子

4、自定义简单版range方法

def range1(start, end, s = 1):
    """
    :param start:起始值 
    :param end: 结束zhi
    :param s: 取值间隔s-1
    :return: 从起始值开始,每间隔s-1个数取值
    """
    while start < end:
        yield start
        start = start + s


a = range1(1,10,2)
print(a.__next__())  # 1
print(a.__next__())  # 3
print(a.__next__())  # 5
print(a.__next__())  # 7
print(a.__next__())  # 9

四、常用内置方法

print(abs(-11.11))  # 求绝对值
l = [0,1,0]
print(all(l))  # 只要有一个为False就返回False
print(any(l))  # 只要有一个位True就返回True


def index():
    username = '我是局部名称空间里面的username'
    print(locals())  # 当前语句在哪个位置 就会返回哪个位置所存储的所有的名字
    print(globals())  # 无论在哪 查看的都是全局名称空间
index()


print(bin(10))
print(oct(10))
print(hex(10))
print(int('0b1010',2))


print(bool(1))
print(bool(0))


s = 'hello'
print(s.encode('utf-8'))
print(bytes(s,encoding='utf-8'))


# 可调用的(可以加括号执行相应功能的)
l = [1,2,3]
def index():
    pass
print(callable(l))
print(callable(index))


print(chr(97))  # 将数字转换成ascii码表对应的字符
print(ord('a'))  # 将字符按照ascii表转成对应的数字


"""
面向对象需要学习的方法
classmethod
delattr
getattr
hasattr
issubclass
property
repr
setattr
super
staticmethod
"""


# dir获取当前对象名称空间里面的名字
l = [1,2,3]
print(dir(l))
#
# import test
# print(dir(test))
# print(test.name)


# divmod  分页器
print(divmod(101,10))
total_num,more = divmod(900,11)
if more:
    total_num += 1
print('总页数:',total_num)


# enumerate 枚举
l = ['a','b']
for i,j in enumerate(l,1):
    print(i,j)


# eval  exec
s = """
print('hello baby~')
x = 1
y = 2
print(x + y)

"""
eval(s)
exec(s)

# eval不支持逻辑代码,只支持一些简单的python代码
s1 = """
print(1 + 2)
for i in range(10):
    print(i)
"""
eval(s1)
exec(s1)

name = 'jason'
s2 = """
name
"""
print(eval(s2))


# format 三种玩法
# {}占位
# {index} 索引
# {name} 指名道姓

# print(globals())


def login():
    """
    一起嗨皮
    :return:
    """
print(help(login))


# isinstance 后面统一改方法判断对象是否属于某个数据类型
n = 1
print(type(n))
print(isinstance(n,list))  # 判断对象是否属于某个数据类型


print(pow(2,3))


print(round(3.4))
常用内置函数

五、面向过程的编程

面向过程编程的思想:类似于设计一条流水线,按照特定的顺序执行程序。可以将复杂的问题流程化,从而变得简单化,但是可扩展性比较差,一旦某一步骤需要修改时,全局都会受到影响。

比如设计一个用户注册功能,可以分三步,分别依次为获取用户输入、处理用户输入信息、存储用户信息。

def get_info():
    while True:
        username = input(">>>:").strip()
        if not username.isalpha():  # 判断字符串不能包含数字
            print('不能包含数字')
            continue
        password = input('>>>:').strip()
        confirm_password = input("confirm>>>:").strip()
        if password == confirm_password:
            d = {
                '1':'user',
                '2':'admin'
            }
            while True:
                print("""
                    1 普通用户
                    2 管理员
                """)
                choice = input('please choice user type to register>>>:').strip()
                if choice not in d:continue
                user_type = d.get(choice)
                operate_data(username,password,user_type)
                break
        else:
            print('两次密码不一致')

# 2.处理用户信息
def operate_data(username,password,user_type):
    # jason|123
    res = '%s|%s|%s\n'%(username,password,user_type)
    save_data(res,'userinfo.txt')

# 3.存储到文件中
def save_data(res,file_name):
    with open(file_name,'a',encoding='utf-8') as f:
        f.write(res)

def register():
    get_info()

register()

一旦需要获取用户的资产等其它信息时,该注册程序的三个步骤全部都要修改。这就是所谓的流程简单化,扩展性较差。

posted on 2019-07-15 19:16  so_interesting  阅读(128)  评论(0编辑  收藏  举报

导航