第八章 三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数
一、 三元表达式,列表推导式,生成器表达式
1. 三元表达式
# 非三元表达式:
x = 12
y = 11
if x > y:
print(x)
else:
print(y)
# 三元表达式
x = 12
y = 11
res = x if x > y else y
print(res)
# 或用函数引用
def max(x,y):
return x if x > y else y
print(max(1,2))
2. 列表推导式
# 非列表推导式用法:
l = []
for i in range(10):
l.append('age%s' %i)
print (l)
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day5/06 列表生成式、字典生成式、生成器表达式.py"
['age0', 'age1', 'age2', 'age3', 'age4', 'age5', 'age6', 'age7', 'age8', 'age9']
# 列表推导式用法:
l = [('age%s'%i) for i in range(10)]
print(l)
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day5/06 列表生成式、字典生成式、生成器表达式.py"
['age0', 'age1', 'age2', 'age3', 'age4', 'age5', 'age6', 'age7', 'age8', 'age9']
练习
- 将names=['egon','alex_sb','wupeiqi','yuanhao']中的名字全部变大写
names=['egon','alex_sb','wupeiqi','yuanhao']
names = [i.upper() for i in names]
print(names)
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day5/06 列表生成式、字典生成式、生成器表达式.py"
['EGON', 'ALEX_SB', 'WUPEIQI', 'YUANHAO']
- 将names=['egon','alex_sb','wupeiqi','yuanhao']中以sb结尾的名字过滤掉,然后打印剩下名字长度
names = ['egon','alex_sb','wupeiqi','yuanhao']
names = [len(i) for i in names if not i.endswith('sb') ]
print(names)
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day5/06 列表生成式、字典生成式、生成器表达式.py"
[4, 7, 7]
4. 字典生成式
d={i:i for i in range(10) if i > 0}
print(d)
userinfo=[('egon','123'),('alex','456'),('wxx','679')]
dic={k:v for k,v in userinfo}
print(dic)
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day5/06 列表生成式、字典生成式、生成器表达式.py"
{1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
{'alex': '456', 'egon': '123', 'wxx': '679'}
5. 生成器表达式
l = ('age%s' %i for i in range(10))
print(l)
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day5/06 列表生成式、字典生成式、生成器表达式.py"
<generator object <genexpr> at 0x102181888> # 打印后是个生成式,既有__next__又有__iter__
二、 函数递归
1. 递归调用的定义
函数递归:函数的递归调用,即在函数调用的过程中,又直接或间接地调用了函数本身
# 递归形式
# 直接调用
def foo()
print('foo01')
foo()
# run
foo() #死循环千万不要这么写,了解即可
# 间接调用
def bar():
print('from bar')
foo()
def foo():
print('from foo')
bar()
2. 递归分为两个阶段:
- 回溯
注意: 一定要在满足某种条件结束回溯,否则的无限递归 - 递推
总结:
- 递归一定要有一个明确地结束条件
- 没进入下一次递归,问题的规模都应该减少
- 在python中没有尾递归优化
items = [1,[2,[3,[4,[5,[6,[7,[8]]]]]]]]
def tell(l):
for i in l:
if type(i) is not list:
print(i)
else:
tell(i)
tell(items)
3. python中的递归效率低且没有尾递归优化
# python中的递归
python中的递归效率低,需要在进入下一次递归时保留当前的状态,在其他语言中可以有解决方法:尾递归优化,即在函数的最后一步(而非最后一行)调用自己;
但是python又没有尾递归,且对递归层级做了限制
# 总结递归的使用:
1. 必须有一个明确的结束条件
2. 每次更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。)
4. 可以修改递归最大深度
import sys
sys.getrecursionlimit()
sys.setrecursionlimit(2000)
n=1
def test():
global n
print(n)
n+=1
test()
test()
# 虽然可以设置,但是因为不是尾递归,仍然要保存栈,内存大小一定,不可能无限递归
三、 匿名函数
1. 什么是匿名函数?
# 匿名就是没有名字
def func(x,y,z=1):
return x+y+z
# 匿名
lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字
func=lambda x,y,z=1:x+y+z
func(1,2,3)
#让其有名字就没有意义
# 强调:
1. 匿名的目的就是要没有名字,给匿名函数赋给一个名字是没有意义的
2. 匿名函数的参数规则,作用域关系与有名函数是一样的
3. 匿名函数的函数体通常是一个表达式,该表达式必须要有一个返回值
2. 有名字的函数与匿名函数的对比
# 有名函数与匿名函数的对比
有名函数:循环使用,保存了名字,通过名字就可以重复引用函数功能
匿名函数:一次性使用,随时定义
应用:max,min,sorted,map,reduce,filter
四、 内置函数
#注意:内置函数id()可以返回一个对象的身份,返回值为整数。这个整数通常对应与该对象在内存中的位置,
但这与python的具体实现有关,不应该作为对身份的定义,即不够精准,最精准的还是以内存地址为准。is运
算符用于比较两个对象的身份,等号比较两个对象的值,内置函数type()则返回一个对象的类型
#更多内置函数:https://docs.python.org/3/library/functions.html?highlight=built#ascii
- max()
max 也基于for
循环
key 是指定比较依据,如果不指定,则通过max内置for循环取到的值进行比较
# 字典的运算:最小值,最大值,排序
salaries={
'egon':3000,
'alex':100000000,
'wupeiqi':10000,
'yuanhao':2000
}
print(max(salaries,key=lambda x:salaries[x])) # 求出最大工资的那个人名
print(min(salaries,key=lambda x:salaries[x])) # 求出最小工资的那个人名
print(sorted(salaries,key=lambda x:salaries[x])) # 升序
print(sorted(salaries,key=lambda x:salaries[x],reverse=True)) # 降序
- map
names=['alex','wupeiqi','yuanhao','liuqingzheng']
l=[name+"_SB" for name in names]
print(l)
#
obj=map(lambda x:x+"_SB",names) #迭代器
print(list(obj))
- filter的应用
names=['alex_sb','wupeiqi_sb','egon','yuanhao_sb','liuqingzheng_sb']
# l=(name for name in names if name.endswith('sb'))
# print(l)
#filter会得到names的迭代器对象obj,然后next(obj)将得到的值传给filter第一个参数指定的函数
# 将函数返回值为True的那个值留下
res=filter(lambda x:x.endswith('sb'),names)
print(list(res))
- format
# 字符串可以提供的参数 `s` `None`
print(format('some string', 's'))
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
some string
print(format('some string'))
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
some string
# 整形数值可以提供的参数有'b' 'c' 'd' 'o' 'x' 'X' 'n' None
print(format(3, 'b')) # 转换成二进制
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
11
print(format(97, 'c')) # 转换unicode成字符
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
a
print(format(11, 'd')) # 转换成10进制
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
11
print(format(11, 'o')) # 转换成8进制
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
13
print(format(11, 'x')) # 转换成16进制,小写字母表示
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
b
print(format(11, 'X')) # 转换成16进制,大写字母表示
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
B
print(format(11, 'n')) # 和d一样
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
11
print(format(11)) # 默认和d一样
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
11
# 浮点数可以提供的参数有 'e' 'E' 'f' 'F' 'g' 'G' 'n' '%' None
print(format(314159267, 'e')) #科学计数法,默认保留6位小数
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3.141593e+08
print(format(314159267, '0.2e')) #科学计数法,指定保留2位小数
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3.14e+08
print(format(314159267, '0.2E')) #科学计数法,指定保留2位小数,采用大写E表示
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3.14E+08
print(format(314159267, 'f')) # 小数点计数法,默认保留6位小数
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
314159267.000000
print(format(314159267, '0.8f')) # 小数点计数法,指定保留8位小数
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
314159267.00000000
print(format(314159267, '0.10f')) # 小数点计数法,指定保留10位小数
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
314159267.0000000000
print(format(3.14e+1000000, 'F')) # 小数点计数法,无穷大转换成大小字母
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
INF
# g的格式化比较特殊,假设p为格式中指定的保留小数位数,先尝试采用科学计数法格式化,得到幂指数exp,如果
# -4<=exp<p,则采用小数计数法,并保留p-1-exp位小数,否则按小数计数法计数,并按p-1保留小数位数
print(format(0.00003141566, '.1g')) # p=1,exp=-5 ==> -4<=exp<p不成立,按科学计数法计数,保留0位小数点
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3e-05
print(format(0.00003141566, '.2g')) # #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留1位小数点
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3.1e-05
print(format(0.00003141566, '.3g')) # p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留2位小数点
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3.14e-05
print(format(0.00003141566, '.3G')) # p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留0位小数点,E使用大写
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3.14E-05
print(format(3.1415926777, '.1g')) # p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留0位小数点
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3
print(format(3.1415926777, '.2g')) # p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留1位小数点
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3.1
print(format(3.1415926777, '.3g')) # p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留2位小数点
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3.14
print(format(0.00003141566, '.1n')) # 和g相同
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3e-05
print(format(0.00003141566, '.3n')) # 和g相同
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3.14e-05
print(format(0.00003141566)) # 和g相同
# run
/usr/local/bin/python3.5 "/Users/xcn/PycharmProjects/oldboy/day6/01 内置函数剩余.py"
3.141566e-05