4.04Day14递推、三元表达式、列表/字典推导式、匿名函数

复习:
1、迭代器:不需要索引的取值方式
2、生成器:通过特殊的语法自定义的迭代器
3、枚举对象:为可迭代对象创建索引(按照迭代的顺序创建索引)

迭代器对象:装有多个值的容器
1. 可用通过.__next__()进行取值
2. 取一个少一个
3. 通过.__iter__()得到的还是自身

优点:可以不用依赖索引的统一取值方式(可以产生装有无限个元素的容器)
缺点:只能从前往后取,一次只能取一个(不能获取元素个数)

可迭代对象:可以被迭代的对象
可以通过.__iter__()转换为迭代器对象

for 循环迭代器:
1. 自动获取操作对象的迭代器对象
2. 内部一次调用一个.__next__()获取值
3. 取到末尾自动处理异常,结束循环
for v in [1, 2, 3].__iter__():
print(v)

重点:
1. for 的工作原理
2. 有哪些可迭代对象

思考:迭代器对象能不能按索引取值 # 有限的可以考虑一下,无限的免谈

枚举对象:
obj = enumerate('abc')
print(obj)
obbj = list(obj)
print(obj[0])
可以将有限的直接强转为list进行索引取值

for i, v in enumerate('abc'):
print(i, v)


生成器:
1. 结构通过函数方式实现
2. 函数内部返回值不是通过return,而是通过yield
3. 生成器(函数)名 + ()不是调用函数,而是得到生成器对象(自定义迭代器对象)
4. 可以通过.__next__()进行取值,取值一次进入到下一个yield

def fn():
# 为得到第一个yield结果的逻辑的代码
yield 1
# 为得到第二个yield结果的逻辑的代码
yield 2
# ...
yield 3
# ...
yield 4
obj = fn()
print(obj) # generator object (生成器对象)
print(list(obj))


今日内容:
1. 三元运算符 | 三目运算符
2. 列表元组推导式 | 字典推导式
3. 递归
4. 匿名函数
5. 内置函数
6. 作业与面向过程概念

一、三元运算符就是 if...else... 的简化语法(语法糖)
前提:if 和 else 只有一条语句

# 判断两数之大
a = 10
b = 20
if a > b:
print(a)
else:
print(b)

# 上面的代码用三元表达式来写就是:
a = 10
b = 20
print(a if a > b else b)

三元运算符不一定要与条件有直接性关系
a = 10
b = 20
print(b if a > b else a) # 取最小值

二、推导式:列表与字典的转换语法糖
列表(元组)推导式
dic = {'a':1, 'b':2, 'c': 3} # => [('a', 1), ('b', 2), ('c', 3)]

res = [(k, v) for k, v in dic.items()]
print(res)
print(tuple(res)) # 将结果的列表tuple一下就可以获得元组了
run==>
[('a', 1), ('b', 2), ('c', 3)]
(('a', 1), ('b', 2), ('c', 3))

字典推导式
ls = [('a', 1), ('b', 2), ('c', 3)] # => {'a': 1, 'b': 2, 'c': 3}
res = {k:v for k, v in ls}
print(res)
run==>
{'a': 1, 'b': 2, 'c': 3}

案例:
range(10) # range可以被推导为列表
range(10) 其实就是一个[1,2,3,4,5,6,7,8,9]的列表
打印显示时是为[1, 10],是python为了节省内存空间的一种显示方式

res_ls = [arg for arg in range(10)]
print(res_ls)

# 迭代出可解压的单列容器,可以推导出字典
enumerate('abc') # 取出其中的元素与其相对应的索引,一一配对为元组放入列表中
res_dic = {k:v for k,v in enumerate('abc')}
print(res_dic)
run==>
{0: 'a', 1: 'b', 2: 'c'}

三、递归
递归:回溯 与 递推

回溯:询问答案的过程
递推:推出答案的过程

前提:*****
回溯到一个有具体结果的值,便会开始递推
回溯与递推的条件要有规律

递归的本质:函数的自我调用(自己调自己)

import sys
sys.setrecursionlimit(100) # 手动设置递归深度
print(sys.getrecursionlimit()) # 默认1000
# 直接调用: 直接调自己
def a():
a() # 执行函数a

a() # 执行函数a

# 间接调用: 调用别人,别人最终调回自己
def b():
c() # 执行函数c

def c():
d() # 执行函数d

def d():
b() # 执行函数b

b() # 执行函数b


递归案例:
# 询问第一个人年龄,回溯条件 小两岁,第五个人说出自己的年龄,推导出第一个人年龄
# 条件:下一个人的年龄比这个人年纪大两岁
def age_get(num):
if num == 1:
return 58
age = age_get(num - 1) - 2
return age

print(age_get(11))

# 阶乘
def factorial(num):
if num == 1:
return 1
factorial_num = factorial(num - 1) * num
return factorial_num

print(factorial(6))


四、匿名函数:没有名字的函数

定义语法:
lambda 参数列表: 一个返回值表达式

没有函数名,没有函数体,只有一个返回值

关键字: lambda | 参数列表省略()
f = lambda x, y: (x +y, x -y) #想要返回多个值就要括号括起来
print(f)
print(f(10, 20))

应用场景:
1. 匿名函数函数地址可以被一个变量接受,该变量就可以作为函数名来使用
2. 结合内置函数来使用:内置函数某些参数需要一个函数地址,
可以复制一个有名函数名,也可以直接赋值匿名函数


# 内置函数max() 可以设置两个参数,后面一个参数需要是一个函数读内存地址
def fn(arg):
print(arg)
return arg

ls = [100, 200, 50, 10]
res = max(ls, key=fn) # 函数fn从前面的ls中取值
print('------------------------')
print(res)
res1 = max(ls, key=lambda ele: ele)
# 直接给后面的参数一个匿名函数用来取值
print(res1)
posted @ 2019-04-04 15:46  输诚  阅读(170)  评论(0编辑  收藏  举报