目录
一、生成器
1、背景
通过列表生成式,我们可以直接创建一个列表,但是,受到内存限制,列表容量肯定是有限的,而且创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间,在Python中,这种一边循环一边计算的机制,称为生成器:generator。
python中生成器是自定义迭代器的一种。
2、生成器如何使用
关键字:yield
当函数中一旦出现了yield关键字,函数在没有被调用的时候仍然是普通函数,但是只要一调用函数,那么,该函数就不是普通函数了,就变成了生成器。
def index():
print('from index')
yield
print('from second index')
yield
res=index() # res就是生成器对象
print(res) # generotar object
生成器其实就是一个自定义的迭代器
res.__next__() -------> 只要你调用next方法,代码就会走到函数中第一个yield关键字所在的位置停住
res.__next__() -------> 代码从上一次yield停住的地方继续往下执行,走到遇到下一个yield停住
3、自定义的range功能
利用生成器的原理实现range函数的功能
def my_range(start, stop=None, step=1):
if not stop: # 意味着只传了一个参数,stop没有值
stop = start
start = 0
while start < stop:
yield start
start += step
print(my_range(0, 20))
for i in my_range(0, 20):
print(i)
for i in my_range(0, 20, 2):
print(i)
for i in my_range(10):
print(i)
4、生成器yield的其他用法
send做了两件事情:
1. 传值给yield
2. 执行__next__
def eater(name):
print('%s:正在吃...' % name)
while True:
food = yield
print('%s正在吃%s' % (name, food))
'''eater就变成了生成器'''
res = eater('jerry') # 生成器对象:generator object
print(res) # <generator object eater at 0x0000021869489B30>
res.__next__() # jerry:正在吃...
# res.__next__()
res.send('包子') # jerry正在吃包子
res.send('水果') # jerry正在吃水果
res.send('水果') # jerry正在吃水果
res.send('水果') # jerry正在吃水果
res.send('水果') # jerry正在吃水果
res.send('水果') # jerry正在吃水果
res.send('水果') # jerry正在吃水果
res.send('水果') # jerry正在吃水果
5、生成器表达式
生成器表达式如果不使用数据,就不给你数据
把迭代器、生成器看成是一个工厂,什么时候需要数据工厂就给你加工数据
目的:就是为了节省内存空间
names_list = ['kevin', 'jerry', 'tony', 'oscar']
res1 = (name for name in names_list)
print(res1) # <generator object <genexpr> at 0x000001E90BF7CAC0>
print(res1.__next__()) # kevin
print(res1.__next__()) # jerry
print(res1.__next__()) # tony
print(res1.__next__()) # oscar
6、yield与return的对比
yield
1. 把函数可以变成生成器,支持next取值
2. yield 后面可以有返回值,并且支持多个
3. yield支持传值(send)
return
1. 代码遇到return就会停止
2. return可以有返回值并且还支持多个,以元组的形式返回
二、常见的内置函数
1、abs()
abs():返回绝对值
# print(abs(10)) # 10
# print(abs(-10)) # 10
2、all()、any()
all():判断可迭代对象中都是真,结果才为真,只要有一个为假,结果就假
any():判断可迭代对象中有一个为真,结果就是真
print(all([1, 2, 3, True, False])) # False
print(any([1, 2, 3, True, False])) # True
3、ascii()
ascii():是ascii码中的返回该值,不是就返回u
4、bool
bool : 布尔型(True,False)
5、bin()
bin():将给的参数转换成二进制
print(bin(10)) # 二进制:0b1010
6、bytes()
bytes():把字符串转化成bytes类型
bs = bytes("今天吃饭了吗", encoding="utf-8")
print(bs)
# #b'\xe4\xbb\x8a\xe5\xa4\xa9\xe5\x90\x83\xe9\xa5\xad\xe4\xba\x86\xe5\x90\x97'
7、callable()
callable() : 用于检查一个对象是否是可调用的,如果返回True, object有可能调用失败, 但如果返回False,那调用绝对不会成功
a = 10
print(callable(a)) # False 变量a不能被调用
def f():
print("hello")
print(callable(f)) # True 函数是可以被调用的
8、chr()、ord()
ord():输入字符找带字符编码的位置
chr():输入位置数字找出对应的字符
print(ord('a')) # 字母a在编码表中的码位:97
print(ord('中')) # '中'字在编码表中的位置:20013
print(chr(65)) # 已知码位,求字符是什么:A
print(chr(19999)) # 丟
9、 dict()
dict():dict 创建一个字典
10、dir()
dir():查看对象的内置属性, 访问的是对象中的__dir__()方法
print(dir(tuple)) # 查看元组的方法
# ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
11、divmod()
divmod():返回商和余数
print(divmod(20,3)) # 求商和余数:(6,2)
12、enumerate()
enumerate():获取集合的枚举对象
lst = ['one','two','three','four','five']
for index, el in enumerate(lst,1): # 把索引和元素一起获取,索引默认从0开始. 可以更改
print(index)
print(el)
# 1
# one
# 2
# two
# 3
# three
# 4
# four
# 5
# five
13、eval() 、exec()
eval() :只能够执行一些较简单的代码
exec() :能够执行一些复杂的python代码
res = """
print(123)
"""
eval(res) # 123
res1 = """
for i in range(10):
print(i)
"""
eval(res1) # SyntaxError: invalid syntax
res = """
print(123)
"""
exec(res) # 123
res1 = """
for i in range(10):
print(i)
"""
exec(res1) # 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
14、fiter() 过滤 (lamda)
语法:fiter(function. Iterable)
function: 用来筛选的函数. 在filter中会自动的把iterable中的元素传递给function. 然后根据function返回的True或者False来判断是否保留留此项数据 , Iterable: 可迭代对象
def func(i): # 判断奇数
return i % 2 == 1
lst = [1,2,3,4,5,6,7,8,9]
l1 = filter(func, lst) # l1是迭代器
print(l1) # <filter object at 0x000001CE3CA98AC8>
print(list(l1)) # [1, 3, 5, 7, 9]
15、float
float:浮点型(小数)
16、format()
format() :与具体数据相关,用于计算各种小数,精算等。
17、help()
help():函数用于查看函数或模块用途的详细说明。
print(help(str)) # 查看字符串的用途
18、hex()
hex(): 将给的参数转换成十六进制
print(hex(10)) # 十六进制:0xa
19、input()
input():获取用户输出的内容
20、int()
int:整型(整数)
21、isinstance()
isinstance():判断某个类是不是某个类的子类
print(isinstance(123, int))
print(isinstance('hello', str))
print(isinstance([1, 2, 3, 4, 5], list))
22、iter()
iter():获取迭代器, 内部实际使用的是__ iter__()方法来获取迭代器
lst = [1,2,3,4,5]
it = iter(lst) # __iter__()获得迭代器
print(it.__next__()) # 1
23、len()
len():返回一个对象中的元素的个数
24、list()
list():将一个可迭代对象转换成列表
print(list((1,2,3,4,5,6))) # [1, 2, 3, 4, 5, 6]
25、locals()、globals():
locals():返回当前作用域中的名字
globals():返回全局作用域中的名字
def func():
a = 10
print(locals()) # 当前作用域中的内容
print(globals()) # 全局作用域中的内容
print("今天内容很多")
func()
# {'a': 10}
# {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__':
# <_frozen_importlib_external.SourceFileLoader object at 0x0000026F8D566080>,
# '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins'
# (built-in)>, '__file__': 'D:/pycharm/练习/week03/new14.py', '__cached__': None,
# 'func': <function func at 0x0000026F8D6B97B8>}
# 今天内容很多
26、map()
map():会根据提供的函数对指定序列列做映射(lamda)
语法 : map(function, iterable)
可以对可迭代对象中的每一个元素进行映射. 分别去执行 function
def f(i):
return i
lst = [1,2,3,4,5,6,7,]
it = map(f, lst) # 把可迭代对象中的每一个元素传递给前面的函数进行处理. 处理的结果会返回成迭代器print(list(it)) # [1, 2, 3, 4, 5, 6, 7]
27、max()
max():求最大值
print(max(7,3,15,9,4,13)) # 求最大值:15
28、min()
min():求最小值
print(min(5,3,9,12,7,2)) # 求最小值:2
29、next()
next():迭代器向下执行一次, 内部实际使用了__ next__()方法返回迭代器的下一个项目
lst = [1,2,3,4,5]
it = iter(lst) # __iter__()获得迭代器
print(it.__next__()) # 1
print(next(it)) # 2 __next__()
print(next(it)) # 3
print(next(it)) # 4
30、oct
oct():将给的参数转换成八进制
print(oct(10)) # 八进制:0o12
31、open()
open() : 用于打开一个文件, 创建一个文件句柄
f = open('file',mode='r',encoding='utf-8')
f.read()
f.close()
32、pow()
pow(a, b):求a的b次幂, 如果有三个参数. 则求完次幂后对第三个数取余
print(pow(10,2,3)) # 如果给了第三个参数. 表示最后取余:1
33、print()
print():打印输出
34、range()
range():生成数据
for i in range(15,-1,-5):
print(i)
# 15
# 10
# 5
# 0
35、roud()
round():四舍五入
print(round(4.50)) # 五舍六入:4
print(round(4.51)) # 5
36、set
set:创建一个集合
37、slice()
slice():列表的切片
lst = [1, 2, 3, 4, 5, 6, 7]
print(lst[1:3:1]) # [2,3]
s = slice(1, 3, 1) # 切片用的
print(lst[s]) # [2,3]
38、str()
str():将数据转化成字符串
print(str(123)+'456') # 123456
39、sum()
sum():求和
print(sum([1,2,3,4,5,6,7,8,9,10])) # 求和:55
40、tuple()
tuple():将一个可迭代对象转换成元组
print(tuple([1,2,3,4,5,6])) # (1, 2, 3, 4, 5, 6)
41、type()
type():如何判断一个数据类型:int、str、list、dict
s = 'hello'
print(type(s) is str)
print(type(111) is int)
print(type([1, 2, 3, 4]) is list)
42、zip()
zip():函数用于将可迭代的对象作为参数, 将对象中对应的元素打包成一个元组, 然后返回由这些元组组成的列表. 如果各个迭代器的元素个数不一致, 则返回列表长度与最短的对象相同。
lst1 = [1, 2, 3, 4, 5, 6]
lst2 = ['醉乡民谣', '驴得水', '放牛班的春天', '美丽人生', '辩护人', '被嫌弃的松子的一生']
lst3 = ['美国', '中国', '法国', '意大利', '韩国', '日本']
print(zip(lst1, lst1, lst3)) # <zip object at 0x00000256CA6C7A88>
for el in zip(lst1, lst2, lst3):
print(el)
# (1, '醉乡民谣', '美国')
# (2, '驴得水', '中国')
# (3, '放牛班的春天', '法国')
# (4, '美丽人生', '意大利')
# (5, '辩护人', '韩国')
# (6, '被嫌弃的松子的一生', '日本')
43、__ import__()
__ import__():用于动态加载类和函数
# 让用户输入一个要导入的模块
import os
name = input("请输入你要导入的模块:")
__import__(name) # 可以动态导入模块