python中可迭代对象_python的可迭代对象

今日所得

迭代器

可迭代对象

迭代器对象

for循环内部原理

生成器

生成器表达式

内会函数

面对过程编程

迭代器

迭代就是指更新换代的过程,要重复进行,而且每次的迭代都必须基于上一次的结果。

我们使用for循环的时候就是把元素从容器里一个个取出来,这种过程其实就是迭代。

迭代器:迭代取值的工具。

迭代器的作用是提供给你一种不依赖索引取值的方式。

需要迭代取值的数据类型有:字符串、列表、元组、字典、集合

迭代是重复更换的过程,每一次的更换(迭代)都是基于上一次的结果,也就是说每一次迭代都要和上次的结果有关系

迭代器:是用于迭代的工具

可以迭代取值的数据类型

字符串

列表

元组

字典

集合

可迭代对象

可以使用内置__iter__(双下划线加iter加双下划线)方法的都叫做可迭代对象

基本数据类型中的可迭代对象有

str  list  tuple  dict  set

文件对象本身就是迭代器对象(所以文件对象执行内置的__iter__之后还是本身,没有任何变化)

res = 'hello'l= [1,2,3,4,5,6]

t= (1,2,3,4,5,6)

s= {1,2,3,4,5,6}

d= {'name':'chen','age':18,'pwd':123}

f= with open ('test.txt','w',encoding='utf-8')

res.__iter__()

l.__iter__()

t.__iter__()

s.__iter__()

d.__iter__()

f.__iter__()

文件对象(文件对象本身就是迭代器对象,执行__iter__之后还是本身,没有变化)

可迭代对象执行内置的__iter__方法后得到的就是该对象的迭代器

迭代器对象

迭代器对象有内置__iter__的方法

有内置__next__的方法

迭代器一定是可迭代对象

可迭代对象不一定是迭代器对象

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

迭代器取值的特点

只能往后依次取,不能从后往前取

l=[1,2,3,4]

iter_l=l.__iter__() #用__iter__将可迭代对象转换成一个迭代器对象

print(iter_l.__next__()) #迭代器取值,调用__next__

print(iter_l.__next__()) #调用一次取一个

print(iter_l.__next__())print(iter_l.__next__())print(iter_l.__next__()) #如果取完了直接报错StopIteration

异常处理

whileTrue:try:print(iter_d.__next__())exceptStopIteration:#print('老母猪生不动了')

break

d = {'name':'jason','password':'123','hobby':'泡m'}

iter_d= d.__iter__() #将字典变成迭代器对象

whileTrue:try:print(iter_d.__next__()) #循环取值

except StopIteration: #异常处理,当出现的异常和你在except后面写的一样时则继续执行下面的代码

print('取完了'

break

for循环内部原理

for循环里的in关键字,跟的是一个可迭代对象,将in后面的对象调用__iter__转换成迭代器

for循环内部的本质

1.让关键字in后面的对象使用__iter__转换成迭代器对象

2.调用__next__迭代取值

3.内部有异常捕获StopIteration,当迭代器里的元素为空时报错,自动结束循环

迭代取值的优点:1.不依赖于索引取值

2.内存中永远只占一份空间,不会导致内存溢出

迭代取值的缺点:1.不能获取指定的元素

2.迭代器里的元素取完后再取,会报StopIteration的错误

d = {'name':'jason','password':'123','hobby':'泡m'}for i ind:print(i)#for 循环后面的in跟的是一个可迭代对象

生成器

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

当函数内有yield关键字的时候,调用该函数不会执行函数体代码,而是将函数变成生成器。

生成器函数:常规函数定义,但是,使用yield语句,而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,是挂起函数的状态,也就是下次可以接着这里执行。

deffunc():print('第一次')yield 1

print('第二次')yield 2

#函数内如果有yield关键字,那么在加括号执行函数的时候并不会触发函数体代码的运行,函数会暂停在yield这个地方,使用__next__就能得到yield后面的返回值#yield既可以返回一个值也可以返回多个值,并且多个值是按照元组的形式返回的

deffunc():print('first')yield 666 #yield后面跟的值就是调用迭代器__next__方法你能得到的值

print('second')yield 777,888,999 #yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回

yield

#函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行

g=func() #生成器初始化:将函数变成迭代器

print(g.__next__()) #输出为666

print(g.__next__()) #输出为(777, 888, 999)

print(g.__next__()) #输出为None

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

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

#yield支持外界为其传参

defdog(name):print('%s 准备开吃'%name)whileTrue:

food= yield

print('%s 吃了 %s'%(name,food))

g= dog('egon')

g.__next__() #必须先将代码运行至yield 才能够为其传值

g.send('狗不理包子') #给yield左边的变量传参 触发了__next__方法

g.send('饺子')>>>:egon 准备开吃

egon 吃了 狗不理包子

egon 吃了 饺子

生成器表达式

res = (i for i in range(1,10) if i != 4) #生成器表达式

print(res)print(res.__next__())print(res.__next__())print(res.__next__())print(res.__next__())##把列表解析的[]换成()得到的就是生成器表达式

不调用__next__方法 生成器内部代码一句都不会运行

生成器表达式通常用在获取较大容器类型数据的时候

#自定义range功能

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

start+= step

常用内置函数方法

abs(-1) #求绝对值

l= [0,1,2]

all(l)#只要有一个为False就返回False

any(l) #只要有一个为True就返回True

deffunc():

name= '局部空间'

print(locals()) #当前语句在哪个位置,就返回哪个位置所存储的所有空间名

print(globals()) #无论在哪,查看的都是全局名称空间

l= [1,2,3]print(dir(1)) #获取该对象所有可以使用的方法

#divmod 分页器

divmod(103,10) #返回两个数(10,3)前一个是商,后一个是余数,用处是网页分页,有余数就加上一页

#enumerate 枚举

l = ['name','age']for i,j in enumerate(l,1)print(i,j)#在元素前加一个索引,并且可以指定索引从哪个数字开始

#eval() exec()

"""这两个都可以识别字符串中的Python语法,eval不支持逻辑代码,只支持一些简单的python代码,exec可以识别逻辑代码"""

print(isinstance(n,list))#判断对象是否属于某个数据类型

print(pow(2,3)) #括号后面的数是前面的数的几次方

print(round(3.4)) #浮点数的四舍五入

#locals

print(locals()) #当前语句在哪个位置 就会返回哪个位置所存储的所有的名字

#globals

print(globals()) #无论在哪 查看的都是全局名称空间

#dir 获取当前对象名称空间里面的名字

l = [1,2,3]print(dir(l))#eval #exec#eval() 函数用来执行一个字符串表达式,并返回表达式的值。#exec 执行储存在字符串或文件中的 Python 语句,相比于 eval,exec可以执行更复杂的 Python 代码.

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

#locals

print(locals()) #当前语句在哪个位置 就会返回哪个位置所存储的所有的名字

#globals

print(globals()) #无论在哪 查看的都是全局名称空间

面对过程编程:就类似于设计一条流水线

好处:将复杂的问题流程化,从而简单化

坏处:可扩展性较差,一旦需要修改,整体都会受到影响

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值