目录
- 一、生成器与yield
- (一)什么是生成器
- 1.生成器
- 2.yield与return
- (二)为什么要有生成器
- (三)如何得到生成器(自定义的迭代器)
- (一)什么是生成器
- 二、面向过程的编程思想
- (一)什么是编程思想
- (二)什么是面向过程
- (三)优点与缺点
- 1.优点:
- 2.缺点:
- 三、三元表达式
- (一)什么是三元表达式
- (二)如何使用
- 四、生成式
- (一)列表生成式
- (二)字典生成式
- (三)集合生成式
- (四)生成器表达式
- 1.创建一个生成器对象有两种方式
- 五、内置函数补充
- (一)abs()
- (二)all()
- (三)any()
- (四)callable()
- (五)进制转换
- (六)chr()与ord()
- (七)divmod()
- (八)enumerate()
一、生成器与yield
(一)什么是生成器
1.生成器
生成器就是一种自定义的迭代器,用来返回多次值。
2.yield与return
(1)return:
只能返回一次值,函数就立即结束了。
(2)yield
①可以挂起函数,保存函数的运行状态。
②可以用来返回多次值。
(二)为什么要有生成器
生成器(自定义迭代器)的优点:节省内存。
(三)如何得到生成器(自定义的迭代器)
在函数内一旦存在yield关键字,调用函数并不会执行函数体代码,会得到一个返回值,该返回值就是我们自定义的生成器。
# 先定义一个函数
def func():
print('11111111111')
print('11111111111')
yield 1, 2
print('22221222222')
yield
print('33333333333')
yield 3
print('44444444444')
g = func()
print(g) #
# 生成器内置有__iter__和__next__方法,所以生成器本身就是一个迭代器
# g.__iter__()
# g.__next__()
# 因而我们可以用next(生成器)触发生成器所对应函数的执行,然后遇到yield停下来,将yield后的值当做本次调用的结果返回
res1 = g.__next__() = next(g) # 11111111111
# 11111111111
print(res1) # (1, 2)
res2 = g.__next__() = next(g) # 22221222222
print(res2) # None
res3 = g.__next__() = next(g) # 33333333333
print(res3) # 3
next(g) # 44444444444
# StopIteration
my_range小示例
# # 应用案列
def my_range(start,stop,step=1):
while start < stop:
yield start # 函数中出现了yield,调用时已不能执行函数体代码,实际上已变成一个生成器generator
start+=step
g=my_range(1,5) #
print(next(g)) # 1 触发函数执行直到遇到yield则停止,将yield后的值返回,并在当前位置挂起函数
print(next(g)) # 2 再次调用next(g),函数从上次暂停的位置继续执行,直到重新遇到yield...
print(next(g)) # 3 重复上一步
print(next(g)) # 4 触发函数执行没有遇到yield则无值返回,即取值完毕抛出异常结束迭代StopIteration
## 既然生成器对象属于迭代器,那么必然可以使用for循环迭代,如下:
for n in my_range(1,5):
print(n) # 1 2 3 4
二、面向过程的编程思想
(一)什么是编程思想
编程思想就是编写程序的套路,与具体的技术点无关。
(二)什么是面向过程
面向过程核心是过程二字,过程就是解决问题的步骤,即先干啥、再干啥、后干啥,基于面向过程编程就好比在设计一条条的流水线。
(三)优点与缺点
1.优点:
将复杂的问题流程化、进而简单化。
2.缺点:
所有环节耦合到一起,环环相扣,如果要修改某个环境,有可能会牵一发而动全身,扩展性差。
三、三元表达式
(一)什么是三元表达式
三元表达式是python为我们提供的一种简化代码的解决方案,语法如下:
res = 条件成立时返回的值 if 条件 else 条件不成立时返回的值
(二)如何使用
针对下述场景
def func(x,y):
if x > y:
return x
else:
return y
res=func(1,2)
print(res) # 2
用三元表达式可以一行解决
x=1
y=2
res=x if x > y else y
print(res) # 2
四、生成式
(一)列表生成式
列表生成式是python为我们提供的一种简化代码的解决方案,用来快速生成列表。
# 列表生成式:
l = ['alex_nb', 'lxx_nb', 'wxx_nb', "xxq_nb", 'egon']
# 取出所有'nb'结尾的组成新的列表
new_l=[]
for name in l:
if name.endswith('nb'):
new_l.append(name)
print(new_l) # ['alex_nb', 'lxx_nb', 'wxx_nb', 'xxq_nb']
new_l=[name for name in l if name.endswith('nb')] # 快速生成新的列表,['alex_nb', 'lxx_nb', 'wxx_nb', 'xxq_nb']
# 把所有小写字母全变成大写
new_l=[name.upper() for name in l]
print(new_l) # ['ALEX_NB', 'LXX_NB', 'WXX_NB', 'XXQ_NB', 'EGON']
# 把所有的名字去掉后缀_nb
new_l=[name.replace('_nb','') for name in l]
print(new_l) # ['alex', 'lxx', 'wxx', 'xxq', 'egon']
(二)字典生成式
# 字典生成式
keys=['name','age','gender']
dic={key:None for key in keys}
print(dic) # {'name': None, 'age': None, 'gender': None}
items=[('name','egon'),('age',18),('gender','male')]
res={k:v for k,v in items if k != 'gender'}
print(res) # {'name': 'egon', 'age': 18}
(三)集合生成式
# 集合生成式
keys=['name','age','gender']
set1={key for key in keys}
print(set1,type(set1)) # {'gender', 'age', 'name'}
(四)生成器表达式
1.创建一个生成器对象有两种方式
(1)一种是调用带yield关键字的函数,
(2)另一种就是生成器表达式,与列表生成式的语法格式相同,只需要将[]换成(),即:
(expression for item in iterable if condition)
对比列表生成式返回的是一个列表,生成器表达式返回的是一个生成器对象。对比列表生成式,生成器表达式的优点是节省内存(一次只产生一个值在内存中)。
g=(i for i in range(6) if i > 3)
# !!!!!!!!!!!强调!!!!!!!!!!!!!!!
# 此刻g内部一个值也没有
print(g,type(g)) # at 0x000001F1CE13D9E0>
print(next(g)) # 4
print(next(g)) # 5
print(next(g)) # StopIteration
如果我们要读取一个大文件的字节数,应该基于生成器表达式的方式完成
with open('a.txt', mode='rt', encoding='utf-8') as f:
# 方式一:
res=0
for line in f:
res+=len(line)
print(res)
# 方式二:
res=sum([len(line) for line in f])
print(res)
# 方式三 :效率最高
res = sum((len(line) for line in f))
# 上述可以简写为如下形式
res = sum(len(line) for line in f)
print(res)
五、内置函数补充
(一)abs()
# 取绝对值
print(abs(-1)) # 1
print(abs(1)) # 1
(二)all()
# 2.1、传入的可迭代对象取出的值,全真则真,一假则假
# 2.2、如果传入的可迭代对象取不出任何值,默认返回True
print(all([1,1,1,True,"abc"])) # True
print(all([1,"",1,True,"abc"])) # False
print(all([])) # True
(三)any()
# 3.1、传入的可迭代对象取出的值,一真则真,全假才假
# 3.2、如果传入的可迭代对象取不出任何值,默认返回False
print(any([0,None,False,"",1])) # True
print(any([])) # False
(四)callable()
# 判断一个变量是否可以加括号被调用为函数
def func():
pass
print(callable(func)) # True
print(callable(len)) # True
print(callable(10)) # False
(五)进制转换
# 10进制转换为二 八 十六 进制
print(bin(11)) # 0b1011
print(oct(11)) # 0o13
print(hex(11)) # 0xb
(六)chr()与ord()
print(ord("a")) # 97
print(chr(97)) # a
(七)divmod()
# 同时取到商与余数
print(divmod(10,3)) # (3, 1)
(八)enumerate()
# 得出可迭代对象的序号与值,迭代无序的字典类型也给出序号
l=[111,222,333]
for i,item in enumerate(l): #i,item=(0,111)
print(i,item)
for i,item in enumerate({"k1":111,"k2":222}): #i,item=(0,111)
print(i,item)