迭代器生成器和模块

三大神器 -迭代器、生成器

1.什么是迭代器(iter)

迭代器是容器型数据类型,只能通过类型转换和生成器来获得迭代器对象

迭代器存储数据的特点:同时可以保存多个数据,没有办法直接查看数据,而是需要先将数据从迭代器中取出来(取出来之后不能再放回去)

所有的容器都可以转换成迭代器

iter1 = iter([10, 20, 30, 40])
print(iter1)  # <list_iterator object at 0x000001F4A9E2C688>

iter2 = iter('abc')
print(iter2)   # <str_iterator object at 0x000001F4A9E2C788>

iter3 = iter({'name': '张三', 'age': 18, 'gender': '男'})
print(iter3)  # <dict_keyiterator object at 0x000001F4A9E23A98>

iter4 = copy(iter1)
print(iter4)   # <list_iterator object at 0x000001F4A9E30688>

2.获取迭代器中的元素

无论通过什么样的方式,只要是将迭代器中的元素拿到了,那么迭代器中就不会再有这个元素(相当于删除了)

iter1 = iter([10, 20, 30, 40])
list1 = list(iter1)
print(list1)   # [10, 20, 30, 40]
list2 = list(iter1)
print(list2)  # []

1.遍历

iter5 = iter('hello!')
for x in iter5:
    print(f'x: {x}')
"""
x: h
x: e
x: l
x: l
x: o
x: !
"""
print(list(iter5))    # []

2.获取单个元素

iter3 = iter({'name': '张三', 'age': 18, 'gender': '男'})

print(next(iter3))    # name
print(next(iter3))    # age
print(next(iter3))    # gender
# print(next(iter3))    # 报错: StopIteration
iter4 = iter([1, 2, 3, 4, 5, 6, 7])
next(iter4)
next(iter4)
print('++++++++++')
for x in iter4:
    print(f'x: {x}')
"""
x: 3
x: 4
x: 5
x: 6
x: 7
"""
# len 无法获取迭代器的长度
# iter5 = iter('hello world!')
# print(len(iter5))   # 报错

2.生成器

1.什么是生成器

  1. 概念1

    是长期就是迭代器

  2. 概念2

    调用一个yield关键字的函数就可以得到一个生成器

def func1():
    print('++++')
    print('----')
    yield


result = func1()
print('result:', result)  
# result: <generator object func1 at 0x0000027528F6D448>

2.生成器产生数据(生成器中的元素是怎样产生的)

生成器能产生多少元素就看执行生成器对应的函数体会遇到几次yield :yield 后面的表达式的结果就是生成器产生的数据

# 示例一:创建一个生成器可以产生3个数据分别是:10, 100, 78
def create_gender1():
    yield 10
    yield 100
    yield 78


gen1 = create_gender1()
print(list(gen1))   # [10, 100, 78]

3.生成器产生数据的原理

当获取生成器的元素的时候,会自动调用生成器关联的函数第一次从函数开始的地方开始执行,直到遇到yield为止并且将 yield 后面的值作为获取到的数据;后面每次执行都是从上次结束的地方开始执行函数直到遇到yield。如果执行到函数结束都没有遇到yield 就不会产生数据(如果用next 去取数据这个函数会报错)

def create_gender2():
    print('函数开始')
    yield 10
    print('++++++')
    yield 98
    print('========')
    yield 100
    print('函数结束')


gen2 = create_gender2()
print('========第1次========')
print(f'元素: {next(gen2)}')  # 元素: 10
print('========第2次========')
print(f'元素: {next(gen2)}')  # 元素: 98
print('========第3次========')
print(f'元素: {next(gen2)}')  # 元素: 100
print('========第4次========')
# print(f'元素: {next(gen2)}')    # 报错:StopIteration
def create_gender3():
    num = 0
    while True:
        num += 1
        yield num


gen3 = create_gender3()
print(next(gen3))
# 练习:写一个产生4位验证码的生成器(验证码有随机的4位数字和字母组成)
from random import choices


def code_gender4():
    alp = 'abcdefghijklmnopqrstuvwxyz'
    str1 = alp + alp.upper() + '0123456789'
    while True:
        yield ''.join(choices(str1, k=4))


gen4 = code_gender4()
print(next(gen4))   # DTNv
print(next(gen4))   # 8r1s
# 注意:每次调用函数都是在创建一个新的生成器对象
def create_gender5():
    for x in range(5):
        yield x


print(next(create_gender5()))    # 0
print(next(create_gender5()))    # 0

gen5 = create_gender5()
print(next(gen5))       # 0
print(next(gen5))       # 1
print(next(gen5))       # 2
print(next(gen5))       # 3

3.生成式

生成式就是生成器的简写

列表推导式的[]变成()就变成了生成式

list1 = [x*2 for x in range(5)]
print(list1)    # [0, 2, 4, 6, 8]

gen1 = (x*2 for x in range(5))
print(gen1)     # <generator object <genexpr> at 0x103dba050>
print(next(gen1))    # 0
print(next(gen1))    # 2


# gen1 = (x*2 for x in range(5)) 相当于:
def func():
    for x in range(5):
        yield x*2


gen1 = func()

4. 模块

1.什么是模块

一个模块就是一个py文件,py文件的文件名就是模块名

2.在一个模块中使用另外一个模块的内容

  1. 那些能用:所有在指定if语句外的全局变量
  2. 怎么使用:需要先导入模块
import 模块名    -   导入后可以使用所有的全局变量;以 '模块名.变量' 来使用变量
from 模块名 import 变量1, 变量2, 变量3,...    -  导入后可以使用指定的变量; 直接使用变量
from 模块名 import * --导入后可以使用所有的全局变量; 直接使用变量 (不推荐使用)
import 模块名 as 新模块名  -  导入模块的时候给模块取别名,以后使用模块的时候使用新名字
from 模块名 import 变量1 as 新变量1, 变量2 as 新变量2, 变量3,...    -  给指定变量取别名

5.导入模块的原理

1.导入模块的原理

当使用import或者from-import 导入模块的时候,系统会自动将被导入的模块中所有的代码都执行一遍

# import test2
# from test2 import a

2.重复导入同一个模块,模块中的内容只会执行一次

3.怎么选择性的执行被导入的内容

在被导入的模块中添加if语句,将不希望被其他模块执行的代码放到if语句中。

if 语句:
if __name__ == '__main__':
    不希望被其他模块执行的代码
    
    
原理:
每个模块都有一个属性:__name__,这个属性是用来保存当前模块的名字;__name__默认值就是模块名(模块对应的py文件的文件名)。当我们直接执行某个模块的时候,这个模块的 __name__属性就会自动变成 '__main__'

6.包的使用

1.什么是包

包就是一种特殊的文件夹(a.里面的文件都是py文件 b.自带一个 __init__.py 的文件)
  1. 直接导入
通过包直接导入模块
通过包导入模块中的数据
  1. 导入的定制

猜你喜欢

转载自blog.csdn.net/weixin_48491902/article/details/107115242