1.函数作为变量
1)函数就是变量
python中声明函数其实就是声明一个类型是function的变量,函数名就是变量名;变量能做的函数都能做
a = 10
def func1():
return '=='
def func2():
return '====='
print(id(a), id(func1))
print(type(a), type(func1))
# 1.变量可以给别的变量赋值
b = a
c = func1
print(c())
# 2.重新给变量赋值
a = 'abc'
func1 = 100
print(func1*2)
func1 = func2
# 3.变量作为容器类型数据的元素
list1 = [a, 10, func1]
print(list1)
print(list1[-1]())
# 4.变量作为函数的参数
def func3(num):
sum1 = num ** num
return sum1
print(func3(3))
a = 4
print(func3(a))
# 函数作为函数的参数 - 实参高阶函数
def func4(fn):
fn()
def func5(x=10):
print(x)
func4(func5)
2)系统实参高阶函数:列表.sort\sorted\max\min...中有个参数key,类型就是function。
key的用法:
key是一个函数,必须有且只有一个参数(代表序列中的元素),还有一个返回值(返回值就是比较标准)
students = [
{'name': 'a', 'age': 22, 'score': 99},
{'name': 'b', 'age': 20, 'score': 29},
{'name': 'c', 'age': 24, 'score': 86},
{'name': 'd', 'age': 17, 'score': 44}
]
def test(x):
print(x)
return x['age']
students.sort(key=test)
print(students)
# 练习:将列表nums中所有元素按各位数的和从小到大排序
nums = [19, 29, 54, 81, 75, 23]
def test1(item):
print(item)
sum1 = 0
for x in str(item):
sum1 += int(x)
return sum1
nums.sort(key=test1)
print(nums)
# max的原理
def ysy_max(seq, key=None):
if key:
list1 = list(seq)
max1 = list1[0]
for item in list1[1:]:
if key(item) > key(max1):
max1 = item
return max1
else:
list1 = list(seq)
max1 = list1[0]
for item in list1[1:]:
if item > max1:
max1 = item
return max1
print(ysy_max([12, 34, 52]))
print(ysy_max('1d2s1'))
print(ysy_max({'name': 'a', 'age': 12}))
print(ysy_max([13, 12, 44], key=lambda item: item % 10))
# 5.变量作为函数的返回值
# 函数作为函数的返回值(返回值高阶函数)
def operation(char):
if char == '+':
def sum1(*nums):
x = 0
for num in nums:
x += num
return x
return sum1
elif char == '*':
def sum2(*nums):
x = 1
for num in nums:
x *= num
return x
return sum2
print(operation('+')(12, 90, 22))
2.装饰器
1)什么是装饰器
装饰器的本质就是函数,是用来给函数添加功能用的
装饰器 = 实参高阶函数 + 返回值高阶函数 + 糖语法
# 实例一:给函数添加功能(统计执行时间的功能)
def func1(x, y):
print(x + y)
func1(10, 20)
def func2():
print(' *')
print('====')
func2()
# 实例二:用实参高阶函数给不同的函数添加相同功能
def statistics_time(fn, *args, **wkargs):
t1 = time.time()
fn(*args, **wkargs)
t2 = time.time()
print('时间:{}s'.format(t2 - t1))
statistics_time(func1, y=1, x=2)
# 实例三:无参装饰器
"""
a.语法
def 函数1(fn):
def 函数2(*args, **kwargs):
实现添加功能的代码
fn(*args, **kwargs)
return 函数2
b.说明:
函数名1 - 装饰器的名字(根据添加的功能来命名)
fn - 类型是函数,指向的是需要添加功能的函数
函数名2 - 实现添加功能的函数,名字随便命名,一般为test
"""
def add_time(fn):
def test(*args, **kwargs):
t1 = time.time()
fn(*args, **kwargs)
t2 = time.time()
print(t2-t1)
return test
@add_time
def func5():
print('5')
func5()
# 实例四:有参装饰器
"""
有参装饰器的写法:
def 装饰器名(参数列表):
def 函数名1(fn):
def test(*args,**kwargs):
fn(*args,**kwargs)
添加新功能
return test
return 函数1
说明:参数列表 - 装饰器添加功能的时候变化的部分通过参数列表来确定
"""
def tag(name):
def func11(fn):
def test(*args, **kwargs):
re_str = fn(*args, **kwargs)
new_str1 = '<%s>' % name + re_str + '<%s>' % name
return new_str1
return test
return func11
@tag(name='p')
def render(text):
# 执行其他操作
return text
练习1:写一些装饰器,实现函数结束调用结束后打印‘调用完成’
def add_print(fn):
def test(*args, **kwargs):
fn(*args, **kwargs)
print('调用完成')
return test
@add_print
def func6(m):
print(m**2)
func6(8)
练习2:写一个装饰器,实现将返回值是整数的函数的返回值以十六进制的形式返回
def hex_result(fn):
def test(*args, **kwargs):
re = fn(*args, **kwargs)
return hex(re)
return test
@hex_result
def func7(m):
return m ** 2
print(func7(2))
3.迭代器
1)什么是迭代器(iter)
迭代器是容器型数据类型(序列),迭代器中的元素只能通过将其他序列转换成迭代器或者创建生成器
迭代器中的元素:如果需要查看元素,需要将元素从迭代器取出,而且一旦取出就不能再放回去
2)创建迭代器
iter(序列) - 将序列转换成迭代器并返回
iter1 = iter('akq')
print(iter1)
iter2 = iter({'name': 'a', 'age': 19})
print(iter2)
3)获取元素
1)获取单个元素
next(迭代器) / 迭代器.next()
item = next(iter2)
print(item) # name
item = next(iter2)
print(item) # age
# item = next(iter2)
# print(item) # 报错:StopIteration
2)遍历迭代器
print('======')
for x in iter1:
print('x:', x)
# 练习:
iter1 = iter('hello')
list1 = list(iter1)
print(list1) # ['h', 'e', 'l', 'l', 'o']
# print(next(iter1)) # 报错:StopIteration
4.生成器
1)什么是生成器
生成器就是迭代器,容器有产生数据的能力。
1)怎么创建生成器:调用一个带有yield关键字的函数,就可以得到一个生成器对象
2)生成器产生数据的原理:
当调用一个带有yield关键字函数的时候,不会执行函数体,也不会获取返回值,而是创建一个生成器;
生成器能产生多少个数据,以及每个数据的值,看执行完函数体会遇到几次yield生成器就可以产生几个数据,
yield后面的数据就是会产生的数据
每次获取生成器的元素的时候,都会去执行相应的函数的函数体,执行到yield为止,取下一个元素,
从上次结束的位置接着往后执行
def func1():
print('=====')
print('+++++')
yield [8, 9]
print('----')
yield 4
re = func1()
print('re:', re)
print(next(re))
print('第一次结束')
print(next(re))
练习:写一个学号生成器,能够产生的学号的范围和学号的前缀创建生成器的时候自己决定
def creat_id(pre, num):
length = len(str(num))
for x in range(num):
yield pre+str(x).zfill(length)
py_creater = creat_id('python', 200)
print(next(py_creater))
5.生成式
1)什么是生成式
生成式就是生成器的一种简写方式
1)形式一:
(表达式 for 变量 in 序列) - 序列有多少个元素,生成器就能产生多少个数据,每次循环表达式的值就是产生数据的值
相当于:
def func1():
for 变量 in 序列:
yield 表达式
2)形式二:
(表达式 for 变量 in 序列 if 条件语句)
def func1():
for 变量 in 序列:
if 条件语句:
yield 表达式
gen1 = (x*2 for x in range(5))
print(gen1)
print(next(gen1), next(gen1))
gen2 = (x*2 for x in range(5) if x % 2)
print(next(gen2))
2)变形
1)列表生成式
[表达式 for 变量 in 序列] 相当于 list((表达式 for 变量 in 序列))
[表达式 for 变量 in 序列 if 条件语句]
2)集合生成式
{表达式 for 变量 in 序列} 相当于 set((表达式 for 变量 in 序列))
{表达式 for 变量 in 序列 if 条件语句}
3)生成式转字典
dict(表达式 for 变量 in 序列)
list1 = [x*2 for x in range(5)]
print(list1)
list2 = [x*2 for x in range(5) if x % 2]
print(list2)
set2 = {x*2 for x in range(5) if x % 2}
print(set2)
dict1 = dict((x*2, x) for x in range(5) if x % 2)
print(dict1)
练习:用一行代码实现交换一个字典的键对,产生新的字典
dict2 = {'a': 1, 'b': 2, 'c': 3}
new_dict2 = dict((dict2[key], key) for key in dict2)
print(new_dict2)