第八章 三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数

一、 三元表达式,列表推导式,生成器表达式

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']

练习

  1. 将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']
  1. 将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. 递归分为两个阶段:

  1. 回溯
    注意: 一定要在满足某种条件结束回溯,否则的无限递归
  2. 递推

总结:

  1. 递归一定要有一个明确地结束条件
  2. 没进入下一次递归,问题的规模都应该减少
  3. 在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 

  1. 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))  # 降序
  1. 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))
  1. 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))
  1. 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
posted @ 2018-05-07 17:31  云原生运维社区  阅读(82)  评论(0编辑  收藏  举报