day13-迭代器、三元表达式、列表推导式、字典生成式、生成器与递归
迭代器
迭代器即迭代的工具,迭代是一个重复的过程,每次重复即是一次迭代,并且每次迭代的结果都是下一次迭代的初始值
可迭代对象
只要拥有__iter__()方法的对象就是可迭代对象,如下:
print('name'.__iter__())
print(['read', 'run',[1,2,3,4]].__iter__())
print(('name',18,('age',14,'weight')).__iter__())
print({'name': 'nick', 'age': 18}.__iter__())
print({1,2,3,4,5}.__iter__())
print(open('a.txt').__iter__())
print(18.__iter__()) # 提示nvalid syntax
def f1():
pass
print(f1.__iter()) # 报错提示函数没有iter方法“AttributeError: 'function' object has no attribute '__iter'”
<str_iterator object at 0x0000011DA1C6AF28>
<list_iterator object at 0x0000011DA1C6AF98>
<tuple_iterator object at 0x0000011DA1C0FB00>
<dict_keyiterator object at 0x0000011DA1A706D8>
<set_iterator object at 0x0000011DA1C68630>
<_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'>
可见:字符串/列表/元组/字典/集合/文件都是可迭代对象
迭代器对象
拥有__iter__()和__next__方法的才是迭代器对象。其中,__next__其实是在遍历可迭代对象的元素,一旦遍历完报错,如
lis_iter = [1,2,3].__iter__()
print(lis_iter.__next__()) # 遍历列表中的第一个元素 1
print(lis_iter.__next__()) # 遍历列表中的第一个元素 2
print(lis_iter.__next__()) # 遍历列表中的第一个元素 3
print(lis_iter.__next__()) # 遍历完后报错
1
2
3
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-23-2aa8b474bc11> in <module>
3 print(lis_iter.__next__()) # 遍历列表中的第一个元素 2
4 print(lis_iter.__next__()) # 遍历列表中的第一个元素 3
----> 5 print(lis_iter.__next__())
StopIteration:
print([1,2,3].__iter__().__iter__()) # 迭代器对象使用__iter__方法后是迭代器对象本身
<list_iterator object at 0x0000011DA1C6A080>
print(open('a.txt').__next__())
print(open('a.txt').__iter__())
# 文件即是可迭代对象也是迭代器对象
Hello world
<_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'>
优点:节省内存空间
缺点:取值麻烦,只能一个一个取,并且只能往后去,值取了就没了;无法使用len()方法获取长度
注意:迭代器对象一定是可迭代对象,但是可迭代对象不一定是迭代器对象
for循环原理
只有字符串、列表和元组依赖索引取值色,而其他可迭代对象都是无法依赖索引取值的,有了迭代器,我们就可以不依赖索引迭代取值了
lis = ['run','read']
lis_iter = lis.__iter__()
while True:
try:
print(lis_iter.__next__())
except:
break
run
read
# 基于for循环,我们可以完全不再依赖索引取值
lis = ['run','read']
for i in lis:
print(i,end=',')
run,read,
for循环的工作原理
- 执行in后对象的lis.iter()方法,得到一个迭代器对象lis_iter
- 执行lis_iter.next(),将得到的值赋给i,然后执行循环体代码
- 重复过程2,直到捕捉到异常结束循环
三元表达式(三目表达式)
# 示例:返回x和y的最大值
x = 20
y = 10
if x > y:
print(x)
else:
print(y)
# 用三元表达式写
x, y = 20, 10
max = x if x > y else y
print(max)
列表推导式
# 示例:求0-9数的平方
lis = []
for i in range(10):
lis.append(i*2)
print(lis)
# 用列表推导式写
lis = [i*2 for i in range(10)]
print(lis)
字典生成式
dic = {i:i**2 for i in range(5)}
print(dic)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
zip()方法
# 拉链函数
res = zip('abcd',[1,2,3,4])
print(res)
dic = dict()
for k,v in res:
dic[k] = v
print(dic)
<zip object at 0x0000011DA1C6E788>
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
zip()函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组
print({k:v for k,v in zip('abcd',[1,2,3,4])})
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
生成器
只要函数内部包含有yield关键字,那么函数名()得到的结果就是生成器,接收值但是不会执行函数内部的代码
def func():
yield
print('from 1')
yield 2
print('from 2')
yield 'a',[1,2,3]
g = func()
print(g)
print(g.__next__())
print(g.__next__())
print(g.__next__())
<generator object func at 0x0000011DA1C1F6D0>
None
from 1
2
from 2
('a', [1, 2, 3])
生成器本质上就是自定义的迭代器,因此可以通过.__next__()方法接收yield返回的值。
yield可以暂停住函数,并且提供当前的返回值
yield默认返回None;有一个返回值时返回一个值;有多个返回值时,以元组的形式接收返回值。但是yield不会结束函数,然后继续下一行代码,直到return。
生成器表达式
tup = (i for i in range(10))
print(tup)
for i in tup:
print(i,end=',')
<generator object <genexpr> at 0x0000011DA1C1F728>
0,1,2,3,4,5,6,7,8,9,
递归
函数递归:它是一种特殊的函数嵌套,但是它在调用中又直接或间接地调用了它自身
def f():
print('from f')
f()
f() # 进入了死循环
如果递归函数不断地调用函数自身,那么这个递归函数就会进入一个死循环,所以必须给递归函数一个明确的结束条件
递归的两个阶段
- 递推:一层一层递归调用下去,进入下一层递归的问题规模都将会减小
- 回溯:递归必须要有一个明确的结束条件,在满足该条件开始一层一层回溯
递归的精髓在于通过不断地重复逼近一个最终的结果
def guess_age(age,count):
age -= 2
count -= 1
if count == 1:
print(age)
return
guess_age(age,count)
guess_age(38,5)
30
day13-迭代器、三元表达式、列表推导式、字典生成式、生成器与递归的更多相关文章
- day19-1 迭代器,三元表达式,列表推导式,字典生成式,
目录 迭代器 可迭代对象 迭代器对象 总结 三元表达式(三目表达式) 列表推导式 字典生成式 迭代器 可迭代对象 拥有iter方法的对象就是可迭代对象 # 以下都是可迭代的对象 st = '123'. ...
- Python入门之三元表达式\列表推导式\生成器表达式\递归匿名函数\内置函数
本章目录: 一.三元表达式.列表推导式.生成器表达式 二.递归调用和二分法 三.匿名函数 四.内置函数 ================================================ ...
- python 三元表达式 列表推导式,生成器表达式。递归,匿名函数, 内置函数
三元表达式 三元表达式仅应用于: 1.条件成立返回一个值 2.条件不成立返回一个值 res = x if x>y else y print(res) name= input("姓名&g ...
- python基础-三元表达式/列表推导式/生成器表达式
1.三元表达式:如果成立返回if前的内容,如果不成立返回else的内容 name=input('姓名>>: ') res='SB' if name == 'alex' else 'NB' ...
- Python-02 生成器表达式,列表推导式
列表推导式和生成器表达式 列表推导式,生成器表达式1,列表推导式比较直观,占内存2,生成器表达式不容易看出内容,省内存. [ 变量(加工后的数据) for 变量i in 可迭代的数据类型 ] 列表 ...
- python笔记3 闭包 装饰器 迭代器 生成器 内置函数 初识递归 列表推导式 字典推导式
闭包 1, 闭包是嵌套在函数中的 2, 闭包是内层函数对外层函数的变量(非全局变量)的引用(改变) 3,闭包需要将其作为一个对象返回,而且必须逐层返回,直至最外层函数的返回值 闭包例子: def a1 ...
- day12函数,三元表达式 ,列表推导式 ,字典推导式,函数对象,名称空间与作用域,函数的嵌套定义
复习 # 字符串的比较 # -- 按照从左往右比较每一个字符,通过字符对应的ascii进行比较 # 函数的参数 # 1)实参与形参: # -- 形参:在函数定义时()中出现的参数 # -- 实参:在函 ...
- day12(表达式,推导式,名称空间与作用域,函数的嵌套定义)
一,复习 # 字符串的比较 # -- 按照从左往右比较每一个字符,通过字符对应的ascll进行比较 # print('a' > 'A') #True # print('ac' > 'ab' ...
- python 全栈开发,Day14(列表推导式,生成器表达式,内置函数)
一.列表生成式 生成1-100的列表 li = [] for i in range(1,101): li.append(i) print(li) 执行输出: [1,2,3...] 生成python1期 ...
随机推荐
- java中普通的顶级类是不能使用static关键字修饰的。只有内部类可以使用static修饰,也可以不使用staitc关键字修饰。
java中普通的顶级类是不能使用static关键字修饰的.只有内部类可以使用static修饰,也可以不使用staitc关键字修饰. java中的类可以是static吗?答案是可以.在java中我们可以 ...
- [Vue-rx] Share RxJS Streams to Avoid Multiple Requests in Vue.js
Splitting a stream into multiple streams causes new subscriptions. You can think of new subscription ...
- Live555研究之中的一个 源码编译
Live555研究之中的一个 源代码编译 Live555 是一个为流媒体提供解决方式的跨平台的C++开源项目,它 ...
- HttpClient的Post和Get訪问网页
一.基础JAR包 Mavenproject下pom.xml需配置的jar包 <dependencies> <dependency> <groupId>junit&l ...
- bootstrap table load数据
直接load数据: $("#button").click(function(){ var name=$("input[name='name']").val(); ...
- algorithm库———count&&countif
algorithm头文件定义了一个count的函数,其功能类似于find.这个函数使用一对迭代器和一个值做参数,返回这个值出现次数的统计结果. 编写程序读取一系列int型数据,并将它们存储到vecto ...
- JAVA不让类实例化的方法
虽然java是面向对象编程,但也要尽可能避免创建不必要的对象,因为创建过多的对象不仅占用系统资源,而且多了很多不必要的创建销毁对象开销. 那么有哪些避免类创建对象的方法吗? 1,定义私有构造函数.这在 ...
- hibernate缓存机制详细分析(一级、二级、查询缓存,非常清晰明白)
本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session级别).二级缓存(sessionFactory级别)以及查询缓存,当然还要讨论下我们的N+1的问题. 随笔虽长,但我相信 ...
- SpringBoot集成Redis来实现缓存技术方案
概述 在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. ...
- [Swift通天遁地]四、网络和线程-(12)使用ReachabilitySwift实现对网络状态的检测
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...