"""
函数: 对某一个特定的功能或者代码块进行封装. 在需要使用该功能的时候直接调用即可
定义:
def 函数的名字():
被封装的功能或者代码块->函数体
调用:
函数的名字()
好处: 让程序更加简洁. 代码更加合理
"""
def buy_cai(): # 定义函数
print("1. 打车")
print("2. 去菜市场")
print("3. 讨价还价")
print("4. 回家")
buy_cai()
print("哄哄孙子")
buy_cai()
print("冲洗马桶")
buy_cai()
print("打打老头")
// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 函数的参数 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * //
"""
参数: 可以在函数调用的时候. 给函数传递一些信息
分类:
1. 形参, 在函数定义的时候. 需要准备一些变量来接收信息
1. 位置参数, 按照位置一个一个的去声明变量
2. 默认值参数, 在函数声明的时候给变量一个默认值, 如果实参不传递信息. 此时默认值生效, 否则就不生效
3. 动态传参.
1. *args, 表示接收所有的位置参数的动态传参----> 元组
2. **kwargs, 表示接收所有的关键字的动态传参---> 词典
顺序*: 位置 > *args > 默认值 > **kwargs
上述参数可以随意搭配使用
2. 实参, 实际在调用的时候传递的信息
1. 位置参数. 按照位置进行传递参数
2. 关键字参数. 按照参数的名字进行传递参数
3. 混合参数.
顺序: 位置参数放前面, 关键字参数放后面 -> 否则报错! 官方不让这么干
实参在执行的时候. 必须要保障形参有数据
"""
# 1.骂谁? 2.骂道什么程度?
def maren(ren, lvl): # 形参
print("1. 怒目而视", ren)
print("2. 验证交涉", ren)
if lvl > 99:
print("3. 死不要脸")
else:
print("3. 你愁啥")
print("4. 骂完手工")
maren("破键盘", 188) # 在调用函数的时候. 才能知道到底骂谁, 骂道什么程度 -> 实参
maren("破鼠标", 10)
maren("破电脑", 999)
请用函数编写一个计算器, 能计算 + - * / 四则运算
a + b
def jisuan(a, opt, b):
if opt == "+":
print(a + b)
elif opt == '-':
print(a - b)
elif opt == '*':
print(a * b)
elif opt == '/':
print(a / b)
else:
print("滚犊子")
jisuan(999, "+", 666)
jisuan(999, "-", 666)
jisuan(999, "*", 666)
jisuan(999, "/", 666)
jisuan(999, "^&*", 666)
// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *实参分类 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** //
def chi(zhu, fu, tang, tian):
print(zhu, fu, tang, tian)
chi("大米饭", "西红柿炒鸡蛋", "紫菜蛋花汤", "哈根达斯")
chi(zhu="小米饭", tang="胡辣汤", fu="韭菜炒大腰子", tian="老中街冰棍")
chi("小米饭", "胡辣汤", tang="韭菜炒大腰子", tian="老中街冰棍") # 可以
chi("小米饭", "胡辣汤", fu="韭菜炒大腰子", tian="老中街冰棍") # 也不行!!fu 被赋值了两次!会导致某个形参没有实参对应,不行
chi() # 实参在执行的时候. 必须要保障形参有数据
// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *形参分类 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** //
def luru(name, age, gender="男"):
print(name, age, gender)
luru("张三", 18)
luru("李四", 28)
luru("王二麻子", 38)
luru("吴老二", 14)
luru("赵敏", 12, "女") # '女' 会覆盖默认形参:'男'
luru("周芷若", 11, "女")
def chi(*food): # * 表示位置参数的动态传参, *接收到的值会被统一放在一个元组里面
print(food)
chi('大米饭', "烧茄子", '紫菜蛋花汤', "哈根达斯") # ('大米饭', '烧茄子', '紫菜蛋花汤', '哈根达斯')
chi("大米饭") # ('大米饭',)
def chi(**food): # ** 表示接收关键字的动态传参, 接收到的所有参数都会被处理成字典
print(food)
chi(fu="木须柿子", zhu="小米饭") # {'fu': '木须柿子', 'zhu': '小米饭'}
def func(a, b, c="哈哈", *args, **kwargs): # 如果这种情况,要么:哈哈 () 要么,xx (xxx)
print(a, b, c, args, kwargs) # 也就是说,默认值:哈哈 和 元组 冲突!!不行!
func(1, 2, 3, 4, 5, 6, hello=456, hahalou=654) # 但凡有2个数字以上,哈哈 就没有了,就有元组
可以推断出:*args
必须在
c = "哈哈"
前面!!!
func(1, 2, hello=456, hahalou=654) # 1 2 哈哈 () {'hello': 456, 'hahalou': 654}
# 何时能产生默认值:通过关键字指定的方式进行修改
def func(a, b, *args, c="哈哈", **kwargs):
print(a, b, c, args, kwargs)
func(1, 2, 3, 4, 5, hello=456, hahalou=654) # 这种情况,c永远是默认值:"哈哈"
func(1, 2, 3, 4, c="呵呵", hello=456, hahalou=654) # 这种方式可以修改c
func(1, 2, 3, 4, hello=456, hahalou=654, c="呵呵") # 都可以!! 这里c,形参上有默认值。所以代替默认值。位置在后面那个地方都行
func(1, 2, 3, 4, hello=456, c="呵呵", hahalou=654) # 这也可以
func(1, 2, c="呵呵", 3, 4, hello=456, hahalou=654) # 这肯定不行哈哈
def func(*args, **kwargs): # 没有限制的接收任何参数
print(args, kwargs)
func() # (), {}
func(1) # (1, ), {}
func(1, 2, 3, 4, 4, a=2) # (1,2,3,4,4), {"a":2}
func(1, 2, 3, 4, c=4, a=2) # (1,2,3,4), {"c":4, "a":2}
stu_lst = ["流川枫", '樱木', "大老王", "隔壁二老王"]
def func(*args):
print(args)
func(stu_lst)
func(stu_lst[0], stu_lst[1], stu_lst[2], stu_lst[3], )
func(*stu_lst) # *在实参位置, 是把列表打散成位置参数进行传递
stu_lst = {"c": 4, "a": 2}
def func(**args):
print(args)
func(**stu_lst) # {'c': 4, 'a': 2} ** 在实参位置, 可以把字典自动转化成关键字参数进行传递
func(c=5, a=7, p=8) # {'c': 5, 'a': 7, 'p': 8}
# func( stu_lst ) # 不行!!!报错。因为 **args 接受的是单个单个的字典。
print(*stu_lst) # c a
def fun(args):
print(args)
fun(stu_lst) # {'c': 4, 'a': 2} 当然可以
// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 返回值 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * //
"""
返回值: 函数执行之后. 会给调用方一个结果. 这个结果就是返回值
关于return:
函数只要执行到了return. 函数就会立即停止并返回内容. 函数内的return的后续的代码不会执行
1. 如果函数内没有return , 此时外界收到的是None
2. 如果写了return
1. 只写了return, 后面不跟数据, 此时接收到的依然是None -> 相当于break
2. return 值 , 此时表示函数有一个返回值, 外界能够收到一个数据 -> 用的最多
3. return 值1, 值2, 值3....., 此时函数有多个返回值, 外界收到的是元组, 并且, 该元组内存放所有的返回值
"""
def func(a, b):
# print(a + b)
return a + b
ret = func(10, 20)
print(ret * 3)
def func():
pass
# return None (默认)
ret = func()
print(ret) # None
def func():
print(123)
return # 会让程序停止. 后续代码不会继续执行. 有点儿像循环里面的break
print(456) # 不会执行
ret = func()
print(ret) # None
// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *Python
的内置函数 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * //
"""
https://www.processon.com/view/link/5dbfcf15e4b09df5518ee260
内置函数: 直接能拿来用的函数
print
input
"""
print("hello world")
s = "123"
i = int(s)
b = bool(s)
f = float(s)
complex
复数: 实部 + 虚部
# bin, oct, hex
a = 18 # 十进制
print(bin(a)) # 0b10010
print(oct(a)) # 0o22
print(hex(a)) # 0x12
a = 0b10010
print(int(a)) # 二进制转化成十进制
# sum, min, max, pow
a = 10
b = 3
print(pow(a, b))
print(a ** b) # 次幂
lst = [12, 456, 32, 18, 64, 57]
print(max(lst))
print(min(lst))
print(sum(lst))
# lst[]内部应该是:
lst = []
for item in lst:
lst.append(item)
s = {1, 2, 3, }
lst = list("呵呵哒") # 内部一定会有一个循环(for)
print(lst) # ['呵', '呵', '哒']
s = slice(1, 4, 2) # [1:4:2]
print("我的天哪我去你的"[s]) # 的哪
format, ord, chr
format
格式化
a = 18
print(format(a, "08b")) # b: 二进制, o: 八进制, x: 十六进制
a = "中" # python的内存中使用的是unicode
print(ord(a)) # 2013 中国的中字在unicode中码位是20013
print(chr(20013)) # 给出编码位置. 展示出文字
for i in range(65536):
print(chr(i) + " ", end="")
enumerate, all, any
print(all([1, "123", '豆沙包'])) # True 当成and来看 t and t and t
print(any([0, "", ''])) # False 当成or来看
lst = ["张无忌", "张翠山", "张三丰", "张大大"]
for item in enumerate(lst):
print(item)
# (0, '张无忌')
# (1, '张翠山')
# (2, '张三丰')
# (3, '张大大')
for index, item in enumerate(lst):
print(index, item)
# 0 张无忌
# 1 张翠山
# 2 张三丰
# 3 张大大
for i in range(len(lst)):
print(i, lst[i])
# 0 张无忌
# 1 张翠山
# 2 张三丰
# 3 张大大
s = "呵呵哒"
print(hash(s)) # 一定是一个数字 -> 想办法转化成内存地址. 然后进行数据的存储 -> 字典(集合)哈希表
print(id(s)) # 直接获取内存地址
# 细节: id(s) hash(s) 每次运行都更新一次
print(help(str)) # 返回源码 你可以点住:ctrl ,再点击目标点,可以查看源码
s = "呵呵哒"
print(help(s))
print(dir(s)) # 当前这个数据能执行哪些操作
def func():
return 1, 2, 3, 4
ret = func()
print(ret) # (1, 2, 3, 4)
// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *函数
下 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** //
"""
函数的嵌套
变量的作用域
闭包
装饰器
def wrapper(fn):
def inner(*args, **kwargs);
ret = fn(*args, **kwargs)
return ret
return inner
@wrapper
def func():
pass
迭代器
生成器
yield
g = (x for x in xx)
推导式
匿名函数
python内置函数_下 sorted, filter, map
"""
// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 作用域 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * //
"""
作用域: 变量的访问权限
总结: 里面访问外面没问题, 外面访问里面不能直接访问到
"""
a = 10 # 全局变量 -> 全局作用域
print(a)
def func(): # 全局的一个函数
b = 20 # 局部变量, 局部作用域
print(a) # 10
func() # 10
print(b) # 不行!!报错!!外部不能访问内部
def func3():
func() # 可以
func3()
def func():
c = 10086
return c # 如果想要在函数外面访问到函数内部的东西. 必须要return
c1 = func()
print(c1)
// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *函数嵌套 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** //
"""
函数可以嵌套函数
综上:
1, 函数可以作为返回值进行返回
2, 函数可以作为参数进行互相传递
函数名实际上就是一个变量名, 都表示一个内存地址
"""
def func1():
pass
def func2():
func1() # 这个叫函数的调用. 不叫嵌套
func2()
def func1():
b = 20
def func2(): # 函数的嵌套, 局部变量
pass
print(b)
func2() # 局部的东西. 一般都是在局部自己访问使用的
print(func1())
def func1():
print(1)
def func2():
print(3)
def func3():
print(5)
print(4)
func3()
print(6)
print(2)
func2()
print(7)
func1() # 1234567
def func():
def inner():
print(123)
print(inner) # <function func.<locals>.inner at 0x000001A315278B80>
# 函数 func 内部 inner 地址
return inner # 返回的是一个函数, 此时我们把一个函数当成一个变量进行返回的
b1 = func() # b1是func的内部inner
print(b1)
b1()
def func():
def inner():
def aa():
print(123)
print(aa)
return inner # 返回的是一个函数, 此时我们把一个函数当成一个变量进行返回的
b1 = func() # b1是func的内部inner
print(b1) # <function func.<locals>.inner at 0x000001AE076B8B80>
b1() # <function func.<locals>.inner.<locals>.aa at 0x000001AE076B9800>
def an():
print(123)
print(an) # <function an at 0x00000176887604A0>
an() # 123
bn = an
print(bn) # <function an at 0x00000176887604A0>
bn()
分析1:
def func():
def inner():
def aa():
def gg():
print(123)
print(aa)
return inner # 返回的是一个函数, 此时我们把一个函数当成一个变量进行返回的
print(func) # <function func at 0x000002D00C6504A0>
print(func()) # <function func.<locals>.inner at 0x000002D00C778B80>
print(func()()) # <function func.<locals>.inner.<locals>.aa at 0x000002D00C779800>
b1 = func() # b1是func的内部inner
print(b1) # <function func.<locals>.inner at 0x000001AE076B8B80>
b1() # <function func.<locals>.inner.<locals>.aa at 0x0000020A3C319800> 等价于 inner()
# func()=inner=b1 b1()=inner()
func()() # func()---->返回: inner inner()---> print(aa)
# <function func.<locals>.inner.<locals>.aa at 0x0000021BC6429800>
print(func()) # 等价于 print(inner) print(inner()) 等价于 print(aa) 下面的分析2可以验证
# func=func func()=inner func()()=inner() inner=inner
func() # 没有输出
a = func
print(a) # <function func at 0x000001DF965404A0>
print(func) # <function func at 0x000001DF965404A0>
分析2:
def func():
def inner():
print(inner, 5)
print(inner)
return inner
func() # <function func.<locals>.inner at 0x000001535E2D8B80>
print(func()) # <function func.<locals>.inner at 0x000001535E2D9800>
# <function func.<locals>.inner at 0x000001535E2D9800>
func()() # <function func.<locals>.inner at 0x000001535E2D98A0>
# <function func.<locals>.inner at 0x000001535E2D98A0> 5
# 代理模式
def func(an): # 此时an收到的是一个函数
print(an) # <function target at 0x000001BE95768B80>
an() # 执行这个函数 # 我是target
def target():
print("我是target")
c = 456
func(target) # 实参可以是函数
//************************************ global nonlocal ****************************************************//
"""
global : 在局部. 引入全局变量
nonlocal: 在局部, 引入外层的局部变量
"""
a = 10
def func():
a = 20 # 创建一个局部变量. 并没有去改变全局变量中的a
func()
print(a) # 10
a = 10
def func():
# 此时我就想在函数内部修改全局的变量a
global a # 把外面的全局变量引入到局部
a = 20 # 创建一个局部变量. 并没有去改变全局变量中的a
func()
print(a) # 20
def func():
a = 10
def func2():
a = 20
func2()
print(a) # 10
func() # 10
def func():
a = 10
def func2():
nonlocal a # 向外找一层. 看看有没有该变量. 如果有就引入, 如果没有, 继续向外一层, 直到全局(不包括)
# 把 a=10拽过来
a = 20
func2()
print(a)
func() #20
我想验证一下:如果没有, 继续向外一层, 直到全局(不包括) 写了一个调用函数:
def func():
a = 10
def func2():
def gg():
def aa():
nonlocal a # 向外找一层. 看看有没有该变量. 如果有就引入, 如果没有, 继续向外一层, 直到全局(不包括)
# 把 a=10拽过来
a = 20
gg()
aa()
print(a)
func2()
func() # 20
哈哈哈哈这个有问题。以后再看看这个吧。吐了~~
//******************************************** 闭包 ******************************************************//
def func():
a = 10
def inner():
print(5)
return a
return inner
a=func() # 只是返回了 inner 而已!!!不会输出5!!
# 此时,这个func()返回的 inner 函数,就是:闭包函数
"""
闭包: 本质, 内层函数对外层函数的局部变量的使用. 此时内层函数被称为闭包函数
1. 可以让一个变量常驻与内存
2. 可以避免全局变量被修改
"""
def func():
a = 10
def inner():
nonlocal a
a += 1
return a
return inner
a=func() # func()=inner=a 10
a() # func()()=inner()=a() 偷偷的:a+1=11
print(a()) # 12
这里有个坑,我想了一会儿,明白了 通过上面的推理,我们可以知道:a()==func()()
请运行一下,下面两个程序:
a=func() # 10 这时func里的print(a) 都对同一个inner进行操作!!
print(a()) # 11
print(a()) # 12
print(a()) # 13
和
print(func()()) # 10 11 func里的print(a:10),内部进入了inner,a--->11 每次对新的inner进行操作,所以一直会重复 10 11
print(func()()) # 10 11 func里的print(a:10),内部进入了inner,a--->11
print(func()()) # 10 11 func里的print(a:10),内部进入了inner,a--->11
为什么等价的东西,会出现不一样的情况呢?很简单。因为,你上面的 三个a()是在对同一个inner()进行操作
而下面的三个func()(),每次都对新的func()里面的inner()进行操作。
//****************************** 装饰器 ********************************************************************//
"""
内容回顾:
1. 函数可以做为参数进行传递
2. 函数可以作为返回值进行返回
3. 函数名称可以当成变量一样进行赋值操作
装饰器: -> 要求记住最后的结论
装饰器本质上是一个闭包
作用:
在不改变原有函数调用的情况下. 给函数增加新的功能.
直白: 可以在函数前后添加新功能, 但是不改原来的代码
在用户登录的地方, 日志.
通用装饰器的写法:
def wrapper(fn): wrapper: 装饰器, fn: 目标函数
def inner(*args, **kwargs):
# 在目标函数执行之前.....
ret = fn(*args, **kwargs) # 执行目标函数
# 在目标函数执行之后.....
return ret
return inner 千万别加()
@wrapper
def target():
pass
target() # => inner()
一个函数可以被多个装饰器装饰.
@wrapper1
@wrapper2
def target():
print('我是目标')
规则和规律 wrapper1 wrapper2 TARGET wrapper2 wrapper1
"""
def func():
def inner():
print("123")
return inner
ret = func()
ret()
def func1():
print("我是函数1")
def func2():
print("我是函数2")
func1 = func2 # 函数可以直接传递
func1() # 等价于 func2()
def guanjia(game):
def inner():
print("打开外挂")
game() # 玩起来了
print('关闭外挂')
return inner
@guanjia # 相当于 play_dnf = guanjia(play_dnf)
def play_dnf():
print('你好啊, 我叫赛利亚, 今天又是美好的一天!')
@guanjia
def play_lol():
print("德玛西亚!!!!!!")
# play_dnf = guanjia(play_dnf) # 让管家把游戏重新封装一遍. 我这边把原来的游戏替换了
# play_lol = guanjia(play_lol) # 让管家把lol也重新封装一下.
play_dnf() # 此时运行的是管家给的内层函数inner
play_lol()
#*****************************
def guanjia(game):
# *, **表示接收所有参数, 打包成元组和字典
def inner(*args, **kwargs): # inner添加了参数, args 一定是一个元组 kwargs 一定是字典 (admin, 123456, "大盖伦")
print("打开外挂")
# *, ** 表示把args元组和kwargs字典打散成 位置参数以及关键字参数传递进去
game(*args, **kwargs) # 玩起来了 # game('admin', '123456', "大盖伦")
print('关闭外挂')
return inner
@guanjia # play_dnf = guanjia(play_dnf)
def play_dnf(username, password):
print("我要开始玩儿dnf了. ", username, password)
print('你好啊, 我叫赛利亚, 今天又是美好的一天!')
@guanjia
def play_lol(username, password, hero):
print("我要开始玩儿lol了. ", username, password, hero)
print("德玛西亚!!!!!!")
play_dnf("admin", "123465") # inner
play_lol("admin", "456789", "大盖伦")
//*********************************************** 返回值 ************************************************
def guanjia(game):
def inner(*args, **kwargs):
print("打开外挂")
ret = game(*args, **kwargs) # 这里是目标函数的执行, 这里是能够拿到从目标函数返回的返回值的.
print('关闭外挂')
return ret
return inner
@guanjia
def play_dnf(username, password):
print("我要开始玩儿dnf了. ", username, password)
print('你好啊, 我叫赛利亚, 今天又是美好的一天!')
return "一把屠龙刀"
def play_lol(username, password, hero):
print("我要开始玩儿lol了. ", username, password, hero)
print("德玛西亚!!!!!!")
ret = play_dnf("admin", "123465") # inner
print(ret)
def wrapper1(fn): # fn: wrapper2.inner
def inner(*args, **kwargs):
print("这里是wrapper1 进入") # 1
ret = fn(*args, **kwargs) # wrapper2.inner
print("这里是wrapper1 出去") # 5
return ret
return inner
def wrapper2(fn): # fn: target
def inner(*args, **kwargs):
print("这里是wrapper2 进入") # 2
ret = fn(*args, **kwargs) # taget
print("这里是wrapper2 出去") # 4
return ret
return inner
@wrapper1 # target = wrapper1(wrapper2.inner) => target: wrapp1.inner
@wrapper2 # target = wrapper2(target) => target: wrapper2.inner
def target():
print('我是目标') # 3
target()
"""
这里是wrapper1 进入
这里是wrapper2 进入
我是目标
这里是wrapper2 出去
这里是wrapper1 出去
"""
//*************************************************** 实战 ************************************************//
login_flag = False
def login_verify(fn):
def inner(*args, **kwargs):
global login_flag
if login_flag == False: # ????
# 这里完成登录校验
print('还未完成用户登录操作')
while 1:
username = input(">>>")
password = input(">>>")
if username == "admin" and password == "123":
print("登录成功")
login_flag = True # 记录登录的状态 下次进行操作时,不用修改
break
else:
print("登录失败, 用户名或密码错误")
ret = fn(*args, **kwargs) # 后续程序的执行
return ret
return inner
@login_verify
def add():
print("添加员工信息")
@login_verify
def delete():
print("删除信息")
@login_verify
def upd():
print("修改信息")
@login_verify
def search():
print("查询员工信息")
add()
upd()
delete()
search()
//*************************************** 迭代器 *********************************************************//
"""
for 变量 in 可迭代:
pass
iterable: 可迭代的东西
iterator: 迭代器
str, list, tuple, dict, set, open()
可迭代的数据类型都会提供一个叫迭代器的东西. 这个迭代器可以帮我们把数据类型中的所有数据逐一的拿到
获取迭代器的两种方案:
1. iter() 内置函数可以直接拿到迭代器
2. __iter__() 特殊方法
从迭代器中拿到数据:
1. next() 内置函数
2. __next__() 特殊方法
for里面一定是要拿迭代器的. 所以所有不可迭代的东西不能用for循环
for循环里面一定有__next__出现
总结: 迭代器统一了不同数据类型的遍历工作
迭代器本身也是可迭代的
迭代器本身的特性:
1. 只能向前不能反复
2. 特别节省内存
3. 惰性机制 什么时候访问下一个,采取执行。不然,一直呆着
"""
for item in 1234:
print(item) # 会报错!!! 因为 1234 没有自带的迭代器,无法遍历。
s = 123
it = iter(123564646) # 不行!!! 可以转化成 iter("123564644")
for mm in it:
print(mm)
it = iter("你叫什么名字啊")
print(it) # <str_iterator object at 0x0000026C0F4E9AB0>
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it)) # StopIteration: 迭代已经停止了. 不可以再次从迭代器中拿数据了 报错
it = "呵呵哒".__iter__()
print(it) # <str_iterator object at 0x0000020CD80AA6B0>
print(it.__next__())
print(it.__next__())
print(next(it)) # 都行
# 模拟for循环工作原理:
s = "我是数据"
it = s.__iter__() # 拿到迭代器
while 1:
try:
data = it.__next__()
print(data) # for循环的循环体
except StopIteration: # 要用特定专属的异常~
break
print(123456)
s = "你好啊, 我叫赛利亚"
it = s.__iter__()
for mm in it: # 说明,迭代器可以被迭代(通过 for 循环遍历) # for mm in s: 也可以!!
print(mm)
//******************************************* 生成器 ***************************************************//
"""
生成器(generator):
生成器的本质就是迭代器
创建生成器的两种方案:
1. 生成器函数
2. 生成器表达式
生成器函数
生成器函数中有一个关键字yield
生成器函数执行的时候, 并不会执行函数, 得到的是生成器.
yield: 只要函数中出现了yield. 它就是一个生成器函数
作用:
1. 可以返回数据
2. 可以分段的执行函数中的内容, 通过__next__()可以执行到下一个yield位置
优势:
用好了, 特别的节省内存
生成器表达式 -> 一次性的
语法: (数据 for循环 if)
"""
def func():
print(123456)
return 999 # yield也有返回的意思.
func() # 输出:123456
def func():
print(123456)
yield 999 # yield也有返回的意思.
func() # 不会输出!! 此时,变成了生成器函数。不是普通函数
def func():
print(123456)
yield 999
ret = func() # 不会输出
print(ret) # <generator object func at 0x115f2dbd0>
ret.__next__() # 123456 返回 999
print(ret.__next__()) # 123456 999
# yield只有执行到next的时候才会返回数据
print(ret.__next__()) # StopIteration 只有一个 yield ,所以只能有一个 ret.__next__()
def func():
print(123) # 1
print(888) # 2
yield 666 # 3
print(444) #4
print(555)
print(777)
yield 999 # 6
ret = func()
ret.__next__() # 123 888 或者 print(ret.__next__()) # 123 888 666
ret.__next__() # 444 555 777 或者 print(ret.__next__()) # 444 555 777 999
ret.__next__() 输出:开始 1 到 yield 之前 (也就是:1,2,...)
print(ret.__next__()) 输出:开始 1 到 yield (也就是:1,2,...,yield )
# 可以分段输出!
def func():
print(444)
return 6
print(999) # 遇到 return ,就会跳过!!无法输出 999
def func():
print(444)
yield 6
print(999) # 第二个 ret.__next__() 会输出!!
去工厂定制10000件衣服 # 一次性定制
def order():
lst = []
for i in range(10000):
lst.append(f"衣服{i}")
return lst
lst = order()
print(lst)
# 优化方案:分批次,减小负担
# 分批次,每次定制50套
def order():
lst = []
for i in range(10000):
lst.append(f"衣服{i}")
if len(lst) == 50:
yield lst
# 下一次拿数据
lst = []
gen = order()
print(gen.__next__()) # ['衣服0', '衣服1', ..... '衣服48', '衣服49']
print(gen.__next__()) # ['衣服50', '衣服51', ......, '衣服98', '衣服99']
......
//******************************************** 推导式 *************************************************//
"""
推导式:
简化代码.
语法:
列表推导式: [数据 for循环 if判断]
集合推导式: {数据 for循环 if判断}
字典推导式: {k:v for循环 if判断}
不要把推导式妖魔化.
(数据 for循环 if判断) -> 不是元组推导式, 根本就没有元组推导式. 这玩意叫生成器表达式
"""
lst = []
for i in range(10):
lst.append(i)
print(lst) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lst = [i for i in range(10)]
print(lst) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 1. 请创建一个列表[1,3,5,7,9]
lst = [i for i in range(1, 10, 2)] # [1, 3, 5, 7, 9]
lst = [i for i in range(10) if i % 2 == 1] # 这也行
print(lst) # [1, 3, 5, 7, 9]
# 2. 生成50件衣服
lst = [f"衣服{i}" for i in range(50)]
print(lst) # ['衣服0', '衣服1', ..... '衣服48', '衣服49']
# 3. 将如下列表中所有的英文字母修改成大写
lst1 = ["allen", "tony", "kevin", "sylar"]
lst2 = [item.upper() for item in lst1]
print(lst2) # ['ALLEN', 'TONY', 'KEVIN', 'SYLAR']
s = {i for i in range(10)}
print(s) # {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
# 4. 请将下列的列表修改成字典, 要求 索引做为key, 数据作为value
lst = ['赵本山', "潘长江", "高达", "奥特曼"]
dic = {i: lst[i] for i in range(len(lst))} # k,v k=i v=lst[i]
print(dic)
//******************************************** 生成器 *************************************************//
gen = [i**2 for i in range(10)]
print(gen) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
gen = (i**2 for i in range(10))
print(gen) # <generator object <genexpr> at 0x0000024F131C64D0> 生成器
print(gen.__next__()) # 0
print(gen.__next__()) # 1
print(gen.__next__()) # 4
gen = (i**2 for i in range(10))
for item in gen:
print(item)
# 输出:0
# 1
# 4
# 9
# .......
lst = list(gen) # 内部有迭代器
print(lst) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
s = list("周杰伦") # list() => for => next()迭代器
print(s) # ['周', '杰', '伦']
print(list) # <class 'list'>
print(list("周杰伦")) # ['周', '杰', '伦']
//*********************************************** 匿名函数 ***********************************************//
"""
匿名函数:
lambda表达式
语法:
变量 = lambda 参数,参数2,参数3....: 返回值
"""
def func():
print(123456)
return 9999
ret = func()
print(ret) #9999
def func(a, b):
return a + b
ret = func(13, 12)
print(ret) # 25
fn = lambda a, b: a + b
print(fn) # <function <lambda> at 0x0000018DB52F04A0>
ret = fn(12, 13)
print(ret) # 25
//*********************************************** 内置函数(下) ***********************************************//
"""
zip: 可以把多个可迭代内容进行合并
sorted: 排序
filter: 筛选
map: 映射
"""
# 0 1 2
lst1 = ["赵本山", "范伟", '苏有朋']
lst2 = [40, 38, 42]
lst3 = ["卖拐", "耳朵大有福", "情深深雨蒙蒙"]
result = []
for i in range(len(lst1)):
first = lst1[i]
second = lst2[i]
third = lst3[i]
result.append((first, second, third))
print(result) # [('赵本山', 40, '卖拐'), ('范伟', 38, '耳朵大有福'), ('苏有朋', 42, '情深深雨蒙蒙')]
result = zip(lst1, lst2, lst3)
print(result) # <zip object at 0x000001EA17F028C0> 迭代器
for item in result:
print(item) # [('赵本山', 40, '卖拐'), ('范伟', 38, '耳朵大有福'), ('苏有朋', 42, '情深深雨蒙蒙')]
lst = list(result)
print(lst) # [('赵本山', 40, '卖拐'), ('范伟', 38, '耳朵大有福'), ('苏有朋', 42, '情深深雨蒙蒙')]
//****************************** locals globals ******************************************************//
a = 188
print(locals()) # 此时locals被写在了全局作用域范围内. 此时看到的就是全局作用域中的内容
# # ......'func': <function func at 0x0000023C643F04A0>, 'a': 188}
def func():
a = 336
print(locals()) # 此时locals放在局部作用域范围, 看到的就是局部作用域的内容
func()
# locals 在全局,那就是显示全局内容 如果在 局部,那就是局部
c = 12
print(globals()) # globals看到的是全局作用域中的内容 无论在哪个位置,都是全局
def func():
a = 336
print(globals()) # ......'func': <function func at 0x0000023C643F04A0>, 'i': 55}
func()
//*********************************** sorted ****** reverse *************************************************//
lst = [16,22,68,1,147,256,49]
s = sorted(lst, reverse=True) # reverse翻转
print(s)
# 1 3 2 4 123132
lst = ["秋", "张二嘎", "比克", "卡卡罗特", "超级宇宙无敌大帅B"]
# def func(item): # item对应的就是列表中的每一项数据
# return len(item)
s = sorted(lst, key=lambda x: len(x))
print(s)
lst = [
{"id": 1, "name": "周润发", "age": 18, "salary": 5200},
{"id": 2, "name": "周星驰", "age": 28, "salary": 511100},
{"id": 3, "name": "周海媚", "age": 78, "salary": 561230},
{"id": 4, "name": "周伯通", "age": 12, "salary": 532100},
{"id": 5, "name": "周大兴", "age": 35, "salary": 53210},
{"id": 6, "name": "周周有辣", "age": 47, "salary": 520},
{"id": 7, "name": "周扒皮", "age": 8, "salary": 12},
]
# 1.根据每个人的年龄排序
s = sorted(lst, key=lambda d: d['age']) # 默认:reverse=False 不会反转
print(s) # 按照年龄,升序
# 2.根据工资进行排序. 从大到小
s = sorted(lst, key=lambda d: d['salary'], reverse=True)
print(s) # 按照工资,降序
//***************************************** filter ****************************************************//
# T T T F F
lst = ["张无忌", "张三丰", "张翠山", "灭绝小师太", "小狐仙"]
f = filter(lambda x: x.startswith("张"), lst) # x.startswith("张") 等价于 x[0]=='张'
print(list(f))
lst = [1,2,3,4,5,6,7,8,9]
result = [item * item for item in lst]
print(result) # [1, 4, 9, 16, 25, 36, 49, 64, 81]
r = map(lambda x: x * x, lst)
print(list(r)) # [1, 4, 9, 16, 25, 36, 49, 64, 81]
//************************************** 递归 *************************************************************//
"""
递归: 函数自己调用自己
递归如果没有任何东西拦截的话. 它默认就是一个死循环
python默认是有递归深度的限制的. 默认的最大递归深度是1000
"""
def func():
print(123)
func()
func()
import sys
print(sys.getrecursionlimit()) # 1000 默认的递归深度
sys.setrecursionlimit(2000)
def xxxx(a, b, c):
xxxxxx
return xxxx
2023.12.19 18:36 拿下python基础!!开始冲向爬虫!!
非常的期待~~~~
06-14
1万+
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
08-21