概述
参考: 教学博客地址1,教学博客地址2,教学博客地址3
函数
一、函数基础
1.1、什么是函数
函数的作用是非常重要的,函数可以说是现代编程中最小的模块单元,其本质上是子程序,就是可以独立执行一个功能的程序,函数的操作方法是将函数体压入栈中,然后传入参数,在计算完毕之后,将return的值返回到调用处,然后将函数从栈中释放出去.
函数对于编程的一般意义来讲,是实现一个特定的功能,并且可以反复调用,减少代码量,在python里没有return语句的话会返回None,所以python里没有真正意义上的过程.所有的都是函数.
面向对象其实是在函数上发展起来的,对象的方法其实就可以看做函数,当然函数在面向对象的语言中也是函数,可以认为面向对象语言是将函数,基础数据类型这些东西做了一个更高层次的封装.
1.2、为何要用函数之不用函数的问题
#1、 代码的组织结构不清晰,可读性差
#2、 遇到重复的功能只能重复编写实现代码,代码冗余
#3、 功能需要扩展时,需要找出所有实现该功能的地方修改之,无法统一管理且维护难度极大
1.3、函数分类
#1、内置函数
为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,参考官网:https://docs.python.org/3/library/functions.html
#2、自定义函数
在一些的场景中内置函数是可能无法满足需求的,这就可能需要根据自身或项目要求来定制自己的函数来实现,后续如果遇到相应的场景,直接设定所定义的函数即可。
1.4、自定义函数
#语法,函数名要能反映其意义
def 函数名(参数1,参数2,参数3,...):
'''注释'''
函数体
return 返回的值
# 一个简单的实例
def hello():
print("你好")
hello() # 直接调用就能显示函数的print结果,但是如果没有return返回过程,那么其结果一定是none
# 比如 login
def login():
username = input("请输入用户名: ")
password = input("请输入密码: ")
if username == "xiong" and password == "123":
return "登陆通过"
return "错误"
print(login())
1.5、函数原则及定义
# 1、函数需要先定义,然后在调用, 但A函数调用B,但B函数在A函数之后,那就会报错
def a():
print("这里是a")
b()
a() # 先引用了a函数,但是b函数还没有引用到内存中,就会出现 b函数没有被定义
def b():
print("这里是b")
# 2、函数定义阶段
# 函数在引用时啥都不会干,只会加载到内存中,但它一旦被调用就会执行函数内的过程
1.6、有参无参
def play():
print("玩耍")
def get(num):
print("你的号码是: {}".format(num))
play()
get(12332112222)
1.7、函数返回值
无return-> pring时会直接打印 None
return 1个值->返回1个值
return 逗号分隔多个值->元组
- 什么时候该有返回值?
- 调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
- 通常有参函数需要有返回值,输入参数,经过计算,得到一个最终的结果
- 什么时候不需要有返回值?
- 调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值
- 通常无参函数不需要有返回值
1.8、形参与实参
# 形参即变量名,实参即变量值,函数调用时,将值绑定到变量名上,函数调用结束,解除绑定
- 位置参数
按照从左到右的顺序定义的参数
位置形参:必选参数
位置实参:按照位置给形参传值
def test(v1,v2): # 2、函数test(形参v1,v2)
print(v1,v2) # 3、当调用之后,获取实参 3 5
test(3,5) # 1、调用 test(传递实参 3 5)
- 关键字参数
按照key=value的形式定义的实参,无需按照位置为形参传值
注意的问题:
1. 关键字实参必须在位置实参右面
2. 对同一个形参不能重复传值
def local(v1, status=False): # 2、关键字参数必须在最右边
return v1 if status else "木有状态" # 3、三元表达式 获取任意一个值返回其状态
print(local("hello")) # 1、当有关键字参数时,可以不用传递 默认就是false
# 失败案例, 这种是不可以的
# non-default argument follows default argument
def the_test(v1, status=False, v2):
return v1 if status else "木有状态"
# duplicate argument 'v1' in function definition
def the_test(v1, v2, v1):
return v1 if v2 else "木有状态"
- 默认参数
# 可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)
注意的问题:
1. 只在定义时赋值一次
2. 默认参数的定义应该在位置形参右面
3. 默认参数通常应该定义成不可变类型
# 与关键字参数差不多
-
可变长参数
可变长指的是实参值的个数不固定 而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs #################################### *args #################################### def test(x, y, *args): print("x: {} ny: {} nargs: {}".format(x, y, args)) test(1, 2, 3, 4, 5, 6, 7, 8) # args: (3, 4, 5, 6, 7, 8) # 如果不做处理,那么传递的就是一个元组加列表的形式 test(1, 2, [1, 2], [111, 22]) # args: ([1, 2], [111, 22]) # 通过 *[] 类似于迭代直接列表做了一个for循环传递到*args当中 test(1, 2, *[1, 2, 3, 5, 6]) # args: (1, 2, 3, 5, 6) #################################### **kwargs #################################### def test(x, **kwargs): print("x: {} nkwargs: {}".format(x, kwargs)) # kwargs: {'k': '123', 'k2': '234', 'k3': '345', 'k4': '456'} test(1, k="123", k2="234", k3="345", k4="456") # 通过迭代的方式传递,先解开然后在传值, 如果直接传字典会报错 test(1, **{'k': '123', 'k2': '234', 'k3': '345', 'k4': '456'}) ############################ *args + **kwargs #################################### def test(*args, **kwargs): print("args: {}nkwargs: {}".format(args, kwargs)) # args: (1, 2, 3) kwargs: {'k': '123', 'k2': '234'} test(1, 2, 3, k="123", k2="234") # args: (1, 2, 3) kwargs: {'k': '123', 'k2': '234'} test(*[1, 2, 3], **{'k': '123', 'k2': '234'})
二、对象及嵌套
2.1、函数对象
函数是第一类对象,即函数可以当作数据传递
#1 可以被引用
#2 可以当作参数传递
#3 返回值可以是函数
#3 可以当作容器类型的元素
# 示例 特性
def foo():
print("foo")
def bar():
print("bar")
dic = {
"foo": foo,
"bar": bar
}
while True:
chiose = input(">>: ").strip()
if chiose in dic:
dic[chiose]()
2.2、嵌套调用
def max(x, y):
return x if x > y else y
def check(a, b, c, d):
res1 = max(a, b) # check嵌套max使用
res2 = max(c, d) # 两两比较,在得出最大值
return max(res1, res2)
print(check(11, 2, 3, 4))
三、名称空间与作用域
- 什么是名称空间
#名称空间:存放名字的地方,三种名称空间,(之前遗留的问题x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方)
-
名称空间的加载顺序
python test.py #1、python解释器先启动,因而首先加载的是:内置名称空间 #2、执行test.py文件,然后以文件为基础,加载全局名称空间 #3、在执行文件的过程中如果调用函数,则临时产生局部名称空间 # 名字的查找顺序 局部名称空间--->全局名称空间--->内置名称空间 #需要注意的是:在全局无法查看局部的,在局部可以查看全局的,如下示例 def foo(): max_num = 111 # 2、min_num相对于foo来说就是一个局部名称变量了 def foo_two(): min_num = 2222 # 1、max_num相对于foo_two来说也是一个全局变量 return min_num foo_two() return max_num foo() # 然后Py里直接执行 max_num 会报出 NameError: name 'max_num' is not defined
-
作用域
#1、作用域即范围 - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效 - 局部范围(局部名称空间属于该范围):临时存活,局部有效 #2、作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下 x=11111 def f1(): def f2(): print(x) return f2 x = 22222 def f3(func): x = 33333 func() f3(f1()) # 最终的结果是 22222 # 先到 全局11111- 22222, 执行f3->f1->f2,f2此时是22222,然后进入x=33333,执行函数func 由于x=33333是局部范围,所以并没有更改x的全局变量,然后在打印 结果为22222
-
作用域查询
#3、查看作用域:globals(),locals() LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__ locals 是函数内的名字空间,包括局部变量和形参 enclosing 外部嵌套函数的名字空间(闭包中常见) globals 全局变量,函数定义所在模块的名字空间 builtins 内置模块的名字空间
-
global与nonlocal关键字
global 将局部变量 修改为全局变量, 这个关键字并不建议使用,如果引用全局可变对象,也就是按引用传递,最好将引用复制一份,否则对全局可变对象直接操作,会修改全局可变对象 max = 123 def f1(): # global max # 1、如果引用了global那么它会修改全局变量 max = 12321 print(max) f1() print(max) # 2、这里得到的结果就是12321 # nonlocal 如果想指定上一层的局部变量,用nonlocal声明 min = "最小值" def f2(): min = "f2里头的" def f3(): nonlocal min # 只修改函数内的上一级 min = "f3里的" print("*" * 10, min) def f4(): print(min) # f3 修改了f2的min值,此时f4得到的全局变量 f2的min就是 f3的结果了 f3() f4() print(min) f2() print(min) ############################ 结果为 ############################ ********** f3里的 f3里的 最小值
四、闭包
4.1、什么是闭包?
# 内部函数包含对外部作用域而非全局作用域的引用
# 提示:之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路,将函数包裹起来
def t1():
n = 0
def t2():
nonlocal n # 修改上层的n值
x = n # 重新赋值x
n += 1 # 每次执行函数+1
return x # 返回修改之后的值
return t2 # 返回x
c = t1()
print(c()) # 0
print(c()) # 1
print(c()) # 2
print(c()) # 3
print(c.__closure__[0].cell_contents) #查看闭包的元素 下一次就是4了
4.2、闭包的意义与应用
#闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
#应用领域:延迟计算(原来我们是传参,现在我们是包起来)
from urllib.request import urlopen
def index(url):
def get():
return urlopen(url).read()
return get
bd=index("http://www.baidu.com") # 得到的是一个内存对象
print(bd().decode('utf-8'))
五、装饰器
装饰器就是闭包函数的一种应用场景
为什么用装饰器
程序中的函数就是具备某一功能的工具, 装饰器就是一个函数,
定义装饰器就是定义一个函数, 只不过装饰器的功能是就是用来给其它函数添加额外的功能,
装饰器( 被装饰的对象 )本身其实是任意可调用的对象,
软件的维护应该遵循开放封闭原则
开放封闭的原则是: 软件一旦上线运行后对修改源代码是封闭的,对扩展功能是开放的
装饰器的实现必须遵循的两大原则
1、不修改被装饰对象的源代码
2、不修改被装饰对象的调用方式
装饰器语法糖
在被装饰的函数上加上 @装饰器 (闭包函数) 等于 函数名=装饰器(函数名)
5.1、无参装饰器
5.1、示例一
简单demo 写法一: 有一定的局限性
import time
def home():
print("welcome home ")
time.sleep(2)
def times(func):
def warpper():
start = time.time()
func() # 执行被装饰的函数
end = time.time()
print("装饰器执行的时长为: {}".format(end-start))
return warpper # 拿到并返回装饰函数的内存地址
home = times(home)
home()
--------------------------------------------------
demo 第二个
def index():
print("welcome to index..")
time.sleep(1)
return 123
def home(tip):
print("this price {}".format(tip))
def timmer(func):
def warpper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print("程序运行时间: {}".format(end-start))
return res
return warpper
index = timmer(index)
print(index())
home = timmer(home)
home(100)
--------------------------------------------------
demo 第三个 装饰器语法糖的方式
import time
timmer函数不变
@timmer # 等于 index = timmer(index)
def index():
.....
@timmer # 等于 home=timmer(home)
def home(tip):
print("this price {}".format(tip))
print(index())
home(100)
5.2、有参装饰器
import time
current_user = {"user": None}
def auth(eng):
def timeer(func):
def wrapper(*args, **kwargs):
if current_user["user"]:
res = func(*args, **kwargs)
return res
username = input("请输入用户: ").strip() # 输入用户 去掉空格
pwd = input("请输入密码: ").strip() # 输入密码 去掉空格
if eng == "file":
if username == "xiong" and pwd == "123":
current_user["user"] = "xiong"
print("登陆成功")
else:
print("登陆失败")
elif eng == "mysql":
print("mysql登陆")
res = func(*args, **kwargs)
return res
return wrapper
return timeer
timeer = auth(eng="file")
@timeer
def index():
print("this's index page")
time.sleep(1)
@auth(eng="file")
def home():
print("this's home page")
time.sleep(1)
index()
home()
装饰器- wraps
**@wraps**接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。
demo-1 - 不带参数的装饰器
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
from functools import wraps
check_auth = {"user": None}
def auth(func):
@wraps(func)
def wrapper(*args, **kwargs):
if check_auth["user"]:
res = func(*args, **kwargs)
return res
user = input("username >>>: ").strip()
passwd = input("passwd >>>: ").strip()
if user == "xiong" and passwd == "123":
res = func(*args, **kwargs)
return res
return "登陆失败"
return wrapper
@auth # 相当于是 login=auth(login)
def login():
return "登陆到了主页"
print(login())
demo-2 - 带参数的装饰器
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
from functools import wraps
check_auth = {"user": None}
def check_auth_types(auth_type="file"):
def auth(func):
@wraps(func)
def wrapper(*args, **kwargs):
if check_auth["user"]:
res = func(*args, **kwargs)
return res
if auth_type == "file":
print("文件认证")
user = input("username >>>: ").strip()
passwd = input("passwd >>>: ").strip()
if user == "xiong" and passwd == "123":
res = func(*args, **kwargs)
return res
if auth_type == "mysql":
return func(*args, **kwargs),"数据库认证"
return "登陆失败"
return wrapper
return auth
x = check_auth_types(auth_type="mysql")
@check_auth_types(auth_type="mysql") # 也可以是 @x
def login():
return "登陆到了主页"
# check_auth_types 传递参数,返回给了auth, 做为有参装饰器继续往里传递执行
print(login())
多个装饰器
# 叠加多个装饰器
# 1. 加载顺序(outter函数的调用顺序):自下而上
# 2. 执行顺序(wrapper函数的执行顺序):自上而下
六、迭代器
迭代器概念
# 迭代器即迭代的工具,那什么是迭代呢?
# 迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值
while True: # 只是单纯地重复,因而不是迭代
print('===>') # 一个无脑的死循环
lis=[1,2,3]
count=0
while count < len(lis): # 迭代 重复的过程,但每次迭代都是下一次的初始值
print(lis[count])
count+=1 # 每次加1, 如果没有+1 那就不是下一次的初始值 == 一个无脑的死循环
为何要有迭代器?什么是可迭代对象?什么是迭代器对象?
#1、为何要有迭代器?
对于序列类型:字符串(str)、列表(list)、元组(tuple),我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器
#2、什么是可迭代对象?
可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下
# 也可通过 dir() 可查看内置函数方法 __iter__
'hello'.__iter__
(1,2,3).__iter__
[1,2,3].__iter__
{'a':1}.__iter__
{'a','b'}.__iter__
open('a.txt').__iter__
#3、什么是迭代器对象?
可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
执行迭代器对象是__next__得到的是迭代器下一个值
执行迭代器对象的__iter__得到的仍然是迭代器本身
而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象
文件类型是迭代器对象
open('a.txt').__iter__()
open('a.txt').__next__()
# 使用
dic = {'a': 1, 'b': 2, 'c': 3}
iter_dic = dic.__iter__() #得到迭代器对象,迭代器对象即有__iter__又有__next__,但是:迭代器.__iter__()得到的仍然是迭代器本身
print(iter_dic, type(iter_dic))
# <dict_keyiterator object at 0x0000020BAF49BB88> <class 'dict_keyiterator'>
print(iter_dic.__next__())
print(iter_dic.__next__())
print(iter_dic.__next__())
# print(iter_dic.__next__()) # StopIteration
#4、注意:
迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象
for循环 - 迭代器
dic = {'a': 1, 'b': 2, 'c': 3}
for i in dic: # dic.__iter__() 得到迭代器对象
print(dic[i]) # 每次循环都是 xx.__next__() 获取值,直到StopIteration
# for循环的工作原理
# 1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
# 2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
# 3: 重复过程2,直到捕捉到异常StopIteration,结束循环
迭代器优缺点
#优点:
- 提供一种统一的、不依赖于索引的迭代取值方式
- 惰性计算,节省内存
#缺点:
- 迭代器的取值不如按照索引的方式灵活,它只能往后取而不能往前退
- 无法预测迭代器的个数
- 无法获取长度(只有在next完毕才知道到底有几个值)
- 一次性的,只能往后走,不能往前退
七、生成器-yield
# 生成器 generator
生成器指的是生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码
# 生成器函数
函数体中包含yield语句的函数,返回生成器对象
生成器对象,是一个可迭代对象,是一个迭代器
生成器对象,是延迟计算、惰性求值的
示例
def yie():
for i in range(5):
yield i
print(type(yie))
print(type(yie())) # <class 'generator'>
y = yie() # 通过生成器生成的对象都是一个内存地址
for i in y:
print(i)
普通的函数调用 fn(),函数会立即执行完毕,但是生成器函数可以使用next函数多次执行
生成器函数等价于生成器表达式,只不过生成器函数可以更加复杂
yield from
def yie():
for x in range(100): yield x
# 等价于
def yie():
yield from range(100)
yield from 是python3.3出现的新语法, 是fro item in iterable: yield item形式的语法糖
八、表达式
1.1、三元表达式
条件成立时的返回值, if 条件 else 条件不成立时时的返回值
def check(x,y):
if x > y:
return x
else:
return y
x=10
y=20
# 三元表达式 如果x 大于 y 最左边为x (true),最右边为如果不大于的结果
res = x if x > y else y # 如上的函数可以简化为这种三元表达式
print(res)
1.2、列表生成式
# 重要: 把列表推导式的[]换成()就是生成器表达式
li=[]
for i in range(10):
li.append(i)
print(li)
# 在列表中循环, 然后将循环的值放到左右就能直接append了
li2 = [i for i in range(10)]
print(li2)
# 列表生成式 只能 for if 不能跟else
name = ["xiong", "xiong2", "xiong3"]
li3 = [i for i in name if i not in "xiong"]
print(li3)
# 循环1到10如果小于5 那么i就加1,
li4 = [i+1 for i in range(1,10) if i<5]
print(li4)
1.3、生成器表达式
# 把列表推导式的[]换成()就是生成器表达式
x = (i for i in range(10))
print(x, type(x))
# <generator object <genexpr> at 0x00000231AB5725E8> <class 'generator'>
# 使用生成器的优点:省内存,一次只产生一个值在内存中,每次执行next只会取出一个
with open("a.txt", "r") as files:
# 生成器刚开始造的时候 代码不会执行, 只能在.__next() 调用的时候才会运行
nums = (len(line) for line in files)
print(max(nums))
1.4、字典生成式
keys=["name", "age", "sex"]
values = ["xiong", "100", "male"]
# zip 拉链函数 将两个值对应成元组 如 (name, xiong)
print(list(zip(keys,values)))
res = {k:v for k,v in zip(keys, values)}
print(res)
# {'name': 'xiong', 'age': '100', 'sex': 'male'}
1.5、元组生成器
tuple(random.randint(0, 255) for i in range(3))
(241, 97, 220)
九、递归与二分法
1.1、什么是递归
# 1、什么是递归
递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身,就是递归调用
递归就是一个无何止的重复过程, 递归必须要有一个明确的结束条件
# 2、代码特点
- 函数内部的 代码 是相同的,只是针对 参数不同,处理的结果不同
- 当参数满足一个条件时,函数不再执行
- 这个通常称为递归的出口,否则会出现死循环
# 3、递归阶段
递归必须要有两个明确的阶段
递推: 一层一层递归调用下去,每进入下一层递归问题的规模都必须有所减少
回溯: 递归必须要有一个明确的结束条件,在满足该条件时结束递推,开始一层一层回溯
递归的精髓在于通过不断地重复逼近一个最终的结果
# 4、递归层级
print(sys.getrecursionlimit()) # 获取递归的层级, 1000层
sys.setrecursionlimit(next()) # 设置递归的层级,但没有多大的意义,如果太多可能会导致内存崩掉
# 5、为什么使用递归
递归本身就是一个重复的过程,while循环本身也是做一个重复的过程,递归能做的事 循环也都能满足,但比如是如下这种使用while就会显得比较麻烦,而直接使用递归就能得出想要的结果
l = [1, [2, [3, [4, [5, [6, [7, [8]]]]]]]]
def dl(l):
for its in l:
if type(its) is list:
dl(its)
else:
print(its)
dl(l)
# 示例2
def age(n):
if n == 1: return 10
return age(n-1)+2 // 递推到n等于1时返回10, 然后取到10每次加2
print(age(5)) 循环五次
1.2、递归-二分法
# 查找列表
search_list = [1, 3, 5, 7, 9, 11, 23, 33, 44, 112, 115, 125, 136, 147, 199]
def search(search_list, num):
two_search = len(search_list) // 2 # # 每次取一半
if two_search == 0:
print("没有这个")
return
if num > search_list[two_search]:
n = search_list[two_search:]
search(n, num)
elif num < search_list[two_search]:
n = search_list[:two_search + 1]
search(n, num)
else:
print("找着了")
search(search_list, 112)
十、匿名函数
# 有名函数,调用函数名可以一直重复使用
# 有名函数
def fun(x, y):
return x + y
print(fun(1, 4))
# 匿名函数, 通常于其它函数一起使用,直接执行就的是一个内存地址, :后的x+y就相当于是return x+y
print(lambda x, y: x + y) # <function <lambda> at 0x000002948ACD47B8>
# 与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字
示例
salaries = {
"axiong": 10000,
"wen": 99000,
"hei": 19999,
"bai": 22222
}
def fun(k):
return salaries[k]
max工作原理:
1、 先将可迭代对象变成 迭代器对象
2、 res=next(可迭代器对象), 将res当作参数传递给max函数,然后将该函数的返回值当作判断依据
# 最大值就是w,但func却只需要一次性使用,这里就可以直接使用匿名函数了
# max(iterable, *[, default = obj, key = func]) -> value
# max(arg1, arg2, *args, *[, key = func]) -> val, key=funue
print(max(salaries, key=fun))
print(max(salaries, key=lambda k:salaries[k])) # wen
print(min(salaries, key=lambda k:salaries[k])) # axiong
sorted
# sorted 排序
print(sorted(names, reverse=True)) # 从大到小
print(sorted(names, reverse=False)) # 从小到大
# 与匿名函数进行配置 sorted(可迭代对象, key=匿名函数, 排序=True/False)
print(sorted(names, key=lambda x:x, reverse=True))
print(sorted(names, key=lambda x:x, reverse=False))
map工作原理
1、 先将可迭代对象变成 迭代器对象
2、 res=next(可迭代器对象), 将res当作参数传递给第一个参数指定的函数,然后将该函数的返回值当作map的结果之一
3、 映射: 将原来的值映射成新的值
# 映射,将列表的旧值映射为新的值
m_name = map(lambda x: x + "XXS", names) # ['heiXXS', 'baiXXS', 'hongXXS', 'nvXXS']
print(list(m_name)) # 如果不使用list 打印的话 打印的结果就是迭代器对象,需要通过 __next__
# 与如下的列表生成式相等
m_name = [name + "xxxx" for name in names]
print(m_name)
filter工作原理
1、 先将可迭代对象变成 迭代器对象
2、 res=next(可迭代器对象), 将res当作参数传递给第一个参数指定的函数,然后filter会判断函数的返回值 的真假,如果为真则留下res
names = ["xiongge", "wo", "ni", "hao"]
# 列表生成器
res = [name for name in names if name.endswith("ge")]
print(res)
# filter 过滤器 filter(匿名函数, 可迭代对象)
f_name = filter(lambda x: not x.endswith("ge"), names)
print(f_name) # <filter object at 0x000002B9433EB240>
print(list(f_name)) # ['wo', 'ni', 'hao']
# 使用lamba过滤 filter 过滤某个条件
语法: lambda i: i %2, range(10) 等于是下面这个函数
def t1(i):
temp=[]
for i in range(10):
temp.append('{0}'.format(i%2))
return temp
y=list(filter(lambda i:i %2, range(10)))
print(y) # [1, 3, 5, 7, 9]
map() 可以批量处理数据,与filter() 相比,输入可以是多个可迭代对象
xx = map(lambda x:x, range(10))
print(list(xx)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
使用递归打印斐波那契数列
# 使用递归打印斐波那契数列
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=" ")
a, b = b, a + b
print(" ")
fib(20)
def flb(a, b, stop):
if a > stop:
return
print(a, end="t")
flb(b, a + b, stop)
# 一个嵌套很多层的列表,如l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]],用递归取出所有的值
l = [1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15]]]]]]]
def gl(l):
if type(l) is list:
for li in l:
gl(li)
else:
print(l, end="t")
gl(l)
十一、内置函数
官方内置函数
Built-in Functions | ||||
---|---|---|---|---|
abs() | delattr() | hash() | memoryview() | set() |
all() | dict() | help() | min() | setattr() |
any() | dir() | hex() | next() | slice() |
ascii() | divmod() | id() | object() | sorted() |
bin() | enumerate() | input() | oct() | staticmethod() |
bool() | eval() | int() | open() | str() |
breakpoint() | exec() | isinstance() | ord() | sum() |
bytearray() | filter() | issubclass() | pow() | super() |
bytes() | float() | iter() | print() | tuple() |
callable() | format() | len() | property() | type() |
chr() | frozenset() | list() | range() | vars() |
classmethod() | getattr() | locals() | repr() | zip() |
compile() | globals() | map() | reversed() | __import__() |
complex() | hasattr() | max() | round() |
11.1、需要了解的函数
# 列表中所有值为真,则为真,如果为空也是真
print(all([1, 2, 3, 4, 5])) # True
# 有一个bool值为真,则为真, 如果为空则是false
print(any([1, 0, False])) # True
# 十进制转二进制
print(bin(11)) # 0b1011
# oct 十进制转八进制
print(oct(9)) # 0o11
# hex 十进制转十六进制
print(hex(19)) # 0x13
# chr() 将数字转换成字符
print(chr(103)) # g
# ord 将字符串转成数字
print(ord("g")) # 103
# dir 判断函数里的所有属性
print(dir(True)) # ['__abs__', '__add__',....]
# pow (3,2,2) 3的2次方取余
print(pow(5,2,2)) # 1
# round(3.5) 四舍五入
print(round(3.99)) # 4
callable() 判断函数是否可被调用
divmod(10,3) 分页使用, 比如31 就是 3,1 总共有30页 余1页
最后
以上就是高大寒风为你收集整理的python-基础-4-函数函数的全部内容,希望文章能够帮你解决python-基础-4-函数函数所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复