迭代器是容器型数据类型,只能通过类型转换和生成器来获得迭代器对象
迭代器存储数据的特点:同时可以保存多个数据,没有办法直接查看数据,而是需要先将数据从迭代器中取出来(取出来之后不能再放回去)
所有的容器都可以转换成迭代器
iter1 = iter([10, 20, 30, 40])
print(iter1) #
iter2 = iter('abc')
print(iter2) #
iter3 = iter({'name': '张三', 'age': 18, 'gender': '男'})
print(iter3) #
iter4 = copy(iter1)
print(iter4) #
无论通过什么样的方式,只要是将迭代器中的元素拿到了,那么迭代器中就不会再有这个元素(相当于删除了)
iter1 = iter([10, 20, 30, 40])
list1 = list(iter1)
print(list1) # [10, 20, 30, 40]
list2 = list(iter1)
print(list2) # []
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)) # []
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)) # 报错
概念1
是长期就是迭代器
概念2
调用一个yield关键字的函数就可以得到一个生成器
def func1():
print('++++')
print('----')
yield
result = func1()
print('result:', result)
# result:
生成器能产生多少元素就看执行生成器对应的函数体会遇到几次yield :yield 后面的表达式的结果就是生成器产生的数据
# 示例一:创建一个生成器可以产生3个数据分别是:10, 100, 78
def create_gender1():
yield 10
yield 100
yield 78
gen1 = create_gender1()
print(list(gen1)) # [10, 100, 78]
当获取生成器的元素的时候,会自动调用生成器关联的函数第一次从函数开始的地方开始执行,直到遇到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
生成式就是生成器的简写
列表推导式的[]变成()就变成了生成式
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) # 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()
一个模块就是一个py文件,py文件的文件名就是模块名
import 模块名 - 导入后可以使用所有的全局变量;以 '模块名.变量' 来使用变量
from 模块名 import 变量1, 变量2, 变量3,... - 导入后可以使用指定的变量; 直接使用变量
from 模块名 import * --导入后可以使用所有的全局变量; 直接使用变量 (不推荐使用)
import 模块名 as 新模块名 - 导入模块的时候给模块取别名,以后使用模块的时候使用新名字
from 模块名 import 变量1 as 新变量1, 变量2 as 新变量2, 变量3,... - 给指定变量取别名
当使用import或者from-import 导入模块的时候,系统会自动将被导入的模块中所有的代码都执行一遍
# import test2
# from test2 import a
在被导入的模块中添加if语句,将不希望被其他模块执行的代码放到if语句中。
if 语句:
if __name__ == '__main__':
不希望被其他模块执行的代码
原理:
每个模块都有一个属性:__name__,这个属性是用来保存当前模块的名字;__name__默认值就是模块名(模块对应的py文件的文件名)。当我们直接执行某个模块的时候,这个模块的 __name__属性就会自动变成 '__main__'
包就是一种特殊的文件夹(a.里面的文件都是py文件 b.自带一个 __init__.py 的文件)
通过包直接导入模块
通过包导入模块中的数据