迭代器 生成器 可迭代对象 迭代器对象 常用内置函数

迭代器

什么是迭代器
迭代,更新换代(重复)的过程,每次的迭代都必须基于上一次的结果
迭代器:迭代取值的工具
为什么要用迭代器
迭代器给你提供了一种不依赖于索引取值的方式
# 需要迭代取值的对象
# 列表 字典 字符串 元组 集合
n = 0
while True:
    print(n)
这里只是简单的重复   死循环 



电脑不好的别轻易尝试啊
冒牌迭代器
 重复的+每次迭代都是基于上一次的结果而来的
l = [1,2,3,4]
s = 'hello'
n = 0
while n < len(l):
    print(s[n])   # h e l l    输出四个数字为什么不输出o    看判断条件
    n += 1
正牌迭代器

可迭代对象


只有内部有__iter__方法的就是可迭代对象

在基本数据类型中可以迭代的对象有
字符串 列表 tuple dict set 文件类型(文件类型本身就是迭代器对象)

n = 1
f = 1.11
s = [1,2,3]
d = {'name':'james','age':'22'}
t = (1,2,3,4,5,6,)
set1 = {1,2,3,4,56,7,7}
file1 = open(r'E:程序第四周xxx.txt','w',encoding='utf-8')

print(s.__iter__())  # <list_iterator object at 0x00000000027A3A20>
print(d.__iter__())  # <dict_keyiterator object at 0x00000000024868B8>
print(t.__iter__())  # <tuple_iterator object at 0x00000000027A3A20>
print(set1.__iter__())  # <set_iterator object at 0x00000000027A93A8>
print(file1.__iter__())  # <_io.TextIOWrapper name='E:\程序\第四周\xxx.txt' mode='w' encoding='utf-8'>


说明这几种数据类型可以被迭代  那么也就是说可迭代对象执行内置的__iter__方法得到的就是该对象的迭代器对象
迭代器取值
迭代器对象(句点符)
1 内置有__iter__方法
2 内置有__next__方法
PS 迭代器一定是可迭代对象
但是可迭代对象不一定是迭代器对象
迭代器取值特点:只能从前向后一次取值 不能倒着取值
 总结可迭代对象/迭代器对象
可迭代对象,内置有__iter__方法
迭代器对象,内置有__iter__ 和 __next__方法的

 迭代取值:
优点
1 可以不依靠索引取值
2 内存内永远只有占用一份空间,不会导致内存溢出
缺点
1 因为不能依靠索引取值,所以不能获取指定的元素
2 当取的元素多余原元素时候就会报StopIteration的错误

生成器
l = [1,2,3,4]
生成一个迭代器
iter_l = l.__iter__()   # 内置有__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__())  # StopIteration    报这个错误  因为值已经取完了
列表
dic = {'name':'james','pwd':'123','hobby':'basketball'}
将这个字典dic转换成迭代器对象
iter_dic = dic.__iter__()
接下来取值
print(iter_dic.__next__())  # name
print(iter_dic.__next__())  # pwd
print(iter_dic.__next__())  # hobby
print(iter_dic.__next__())  # StopIteration 又是这个错误 那说明字典中的key已经被我们取完了
字典
异常处理
while
True: try: print(iter_d.__next__()) except StopIteration: # print('老母猪生不动了') break 当在取值的时候如果报错信息是 StopIteration 那么pycharm就会提示你 然后结束循环取值

for循环的本质

# 用了这么久的for循环取值,一直不知道什么原理吧,那就来搂一眼
# for 循环结构
# for 变量名 in 一个可迭代对象 也就是说 for循环 后面的容器类型 必须是可迭代对象


for循环本质:
1 将in后面的容器类型调用__iter__转型成迭代器对象
2 调用__next__方法依次取值
3 内部有异常捕获 StopIteration 时候 __next__ 会自动循环结束 也就是错与元素个数时候会报StopIteration这个错


生成器   本身就是一个迭代器   只不过是我们自己定义的迭代器
那就自己定义一个
def func():
    print('frist')  #frist
    yield  666  # 666
    print('second')  # second
    yield  777  # 777
    print('third')  # third
    yield  888  # 888
    print('forth')  # forth
    yield  # None

# yield后面的就是在调用迭代器__next__方法    输出你可以得到的值
# yield既可以返回一个值也可以返回多个值  多个值的返回类型是元组

g = func()  # 现将生成器初始化:将函数变成迭代器
print(g)  # 出来个老母猪    下面开始下仔仔
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
# print(g.__next__())  # StopIteration
View Code
自定义一个range函数
print(range(10))  #   老母猪 range(0, 10)
看一下range是这么工作的
for i in range(10):
    print(i)


def my_range(start, end, step=1):
    while start < end:
        yield start
        start += step


for j in my_range(1, 100, 2):
    print(j)

yield(纯了解)

yield支持外界为其传参
def dog(name):
print('%s 准备开吃'%name)
while True:
food = yield
print('%s 吃了 %s'%(name,food))
def index():
pass

当函数内有yield关键字的时候,调用该函数不会执行函数体代码
而是将函数变成生成器
g = dog('egon')
g.__next__() # 必须先将代码运行至yield 才能够为其传值
g.send('狗不理包子') # 给yield左边的变量传参 触发了__next__方法
g.send('饺子')


yield
1.帮你提供了一种自定义生成器方式
2.会帮你将函数的运行状态暂停住
3.可以返回值

与return之间异同点
相同点:都可以返回值,并且都可以返回多个
不同点:
yield可以返回多次值,而return只能返回一次函数立即结束
yield还可以接受外部传入的值

生成器表达式
# 生成器表达式
res = (i for i in range(1,1000000) if i!= 4)  # 生成器表达式   有木有发现这个是按照推理应该是元组生成式  不不不   没有元组生成式
print(res)    # <generator object <genexpr> at 0x00000000024ADDB0>    看来是个老母猪  所以又要让老母猪下崽崽了
'''
生成器不会主动的执任何一行代码
必须通过__next__触发代码的运行
'''
print(res.__next__())  # 1
print(res.__next__())  # 2
print(res.__next__())  # 3
print(res.__next__())  # 5

常用的内置函数

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

    username = '我是局部名称空间里面的username'
    print(locals())  # 当前语句在哪个位置 就会返回哪个位置所存储的所有的名字
    print(globals())  # 无论在哪 查看的都是全局名称空间
index()
print(bin(10))  # 0b1010
print(oct(10))  # 0o12
print(hex(10))  # 0xa
print(int('0b1010',2))  # 10

print(bool(1))  # True
print(bool(0))  # False


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

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





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


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))  # 8   2的3次方


print(round(3.4))  # 四舍五入

"""
面向对象需要学习的方法
classmethod
delattr
getattr
hasattr
issubclass
property
repr
setattr
super
staticmethod
"""
原文地址:https://www.cnblogs.com/xuzhaolong/p/11190828.html