# 函数返回数=0,返回None
# 函数返回数=1,返回实际值
# 函数返回数>1,返回一个元组
# 函数参数
# 形参 不占内存空间,只有在调用时才会分配内存单元,调用结束后会释放内存
# 实参 可以是常量 变量 函数 等等
# 函数遇到return就会结束运行
# 位置参数和关键字参数
# 参数组 **字典 *列表
############################################################
# 全局变量和局部变量
# def test01(x):
# '''
# 注释
# :param x:
# :return:
# '''
# y = 2 * x + 1
# print(y)
# print('test01')
#
#
# def test02(x):
# '''
# 注释
# :param x:
# :return:
# '''
# y = 2 * x + 1
# print(y)
# print('test02')
# return y
#
#
# def test03(x):
# '''
# 注释
# :param x:
# :return:
# '''
# y = 2 * x + 1
# print(y)
# print('test03')
# return 1, 3, 4, ['er', 'ere']
#
#
# v1 = test01(1)
# v2 = test02(2)
# v3 = test03(3)
# print(v1)
# print(v2)
# print(v3)
# # 位置参数和关键字参数 若混合使用,位置参数必须在关键字参数左边
# def test(x, y, z):
# print(x)
#
#
# test(1, 2, 3) # 位置参数,必须一一对应,缺一不可
# test(z=2, y=1, x=4) # 关键字参数,无需一一对应,缺一不可
# test(1, z=3, y=4) # 若混合使用,位置参数必须在关键字参数左边
# 默认参数 调用时,不传入实参则使用默认值,传入则使用传入值
# def test(x, y=None):
# print(x)
# print(y)
#
#
# test(3, 'bububg')
# 参数组 **字典 *列表
# def test(x,*args): #args 会给除x后的多个值,当做一个元组
# print(x)
# print(args)
# test(1,3,45,3,2,1)
# test(1,*[9,0,9])
# test(1,*[9,0,9])
# def test(x,**kwargs): #args 会给除x后的多个值,当做一个元组
# print(x)
# print(kwargs)
# test(1,z=2,y=3)
# test(1,z=2,y=3)
# test(2,**{'da':'de'})
# #test(1,y=2,y=3) #一个参数不能传两个值
# def test(x,*args,**kwargs): #参数 列表形式需要在字典前面,否则报错
# print(x)
# print(args)
# print(kwargs)
# test(1,2,34,5,z=2,y=3)
# test(1,*[1,3,5],z=2,y=3)
# test(1,z=2,y=3)
# test(2,**{'da':'de'})
#########################全局变量和局部变量##########################规范 全局变量大写 局部变量小写
# 函数优先使用局部变量,若函数内无该变量,则往外层寻找变量,直到找到该变量
# 函数变量需要使用全局变量时,若函数体内无global关键字,且全局变量为不可变类型,则只能读取全局变量,无法重新赋值
# 接上句,对应全局变量为可变对象,可以对内部元素进行操作
# 函数使用global关键字,可对全局变量,读取和赋值
# name = 'alex' #全局变量
# def change_name():
# print('change name',name) #可以调用全局变量
# change_name()
# def change_name():
# name = 'didjfdi' #局部变量,改变值不会改变全局变量name值
# print('change name',name)
# change_name()
# def change_name():
# global name #定义全局变量,改变该变量值会改变全局变量name值
# name = 'didjfdi'
# print('change name',name)
# change_name()
# print(name)
# list1=['hii','ddin']
# def change_name():
# list1[1]='de' #对应全局变量为可变对象,可以对内部元素进行操作
# print('change name',list1)
# change_name()
# print(list1)
# name = 'alex'
# def change_name():
# name = 'dd'
# print('change name',name)
# def new():
# nonlocal name #指上一级变量
# name = 'de'
# new()
# print(name)
# change_name()
# print(name)
##############################前向引用###############################33
############################递归###################################
# 函数体内调用自己,必须明确一个结束条件,容易死循环
# 效率不高,内存溢出
#
# def calc(n):
# print(n)
# calc(n)
# calc(10) #死循环
# def calc(n):
# print(n)
# if int(n // 2) == 0: #添加一个结束条件
# return n
# res = calc(int(n / 2))
# print(n)
# return res
# a = calc(10)
# print(a)
import time
#
# name_list = ['张三', '李四', '王五', 'alex', 'wendy', 'smis']
# def ask_way(name_list):
# if len(name_list) == 0:
# return('没有人知道')
#
# name = name_list.pop(0)
# if name == '王五':
# return('%s说我知道'%name)
#
# print('%s 你好,你知道路怎么走吗?' % name)
# print('我不知道怎么走,我帮你问%s' % name_list[0])
# # time.sleep(3)
# res = ask_way(name_list)
# print('%s问路的结果是: %s'%(name,res))
# return res
#
#
# a=ask_way(name_list)
# print(a)
##################作用域##############
# name = 'alex'
# def foo():
# name = 'sdfdf'
# def bar():
# name = 'fefe'
# print(name)
# return '这是个啥'
# return bar()
#
# a=foo()
# print(a)
# name = 'a'
# def foo():
# name = 'deij'
#
# def bar():
# name = 'dfeew'
#
# def tt():
# print(name)
#
# return tt #加括号是运行,不加括号返回函数地址
#
# return bar
#
# a=foo()()() #foo()返回bar内存地址 foo()()返回tt内存地址 foo()()()执行tt tt无返回值,返回None
# print(foo()())
#
# a = foo
# print(a) #返回函数地址
#
# a = foo()
# print(a) #返回bar函数地址
# ########################匿名函数 ############################
# 一般没有复杂的逻辑,表达式一行搞定且必须有返回一个值
# 形参不会固定
# 不独立存在,一般跟其他函数共同使用
# def calc(x):
# return x + 1
# # 定义
# lambda x,y: x +y+ 1
# lambda x,y:(x,y+ 1) #返回多个值,需要加括号
# func = lambda x,y: x +y+ 1
# print(func(1,2))
###############高阶函数#########################
# 1.把函数当着参数传给另外一个函数
# 2.返回值包含函数
# def test1(n):
# print(n)
# def test2(name):
# print('%s hello' %name)
# test1(test2('alex'))
# def test1(n):
# print(n)
# def test2(name):
# print('%s hello' %name)
# return test1 #返回函数test1的地址
# a=test2('wendy')
# print(a)
# def test1(n):
# print(n)
# return '这是test1的返回值'
# def test2(name):
# print('%s hello' %name)
# return test1('a') #执行test1
# a=test2('wendy')
# print(a)
####################尾调用优化############################
# 在函数最后一步调用另外一个函数(最后一行不一定是函数最后一步),不用保存上一次调用的状态
# 递归存在内存消耗大的风险,可以对此进行优化
#尾调用
# def bar(n):
# return n
# def foo(x):
# return bar(x)
#
#
# def test(x):
# if x>1:
# return True
# elif x==1:
# return False
# else:
# return x
# a = test(0)
# print(a)
############################3map函数###############################
#map() 会根据提供的函数对指定序列做映射,Python 3 返回一个迭代器
l1 = [1,2,3,45,6]
a = map(lambda x:x+1,l1)
print(list(a)) #[2, 3, 4, 46, 7]
#################################filter函数##########################
#filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。同样是返回一个迭代器对象
list1 = ['adse','dafea','adasef','edsfe']
print(list(filter(lambda n:n.startswith('a'),list1))) #['adse', 'adasef']
print(abs(-1)) #取绝对值
print(all([ ])) #做布尔运算,所有元素为真,则返回真,有一个为假,返回false,若为空,也将返回True