01.recode
1.函数的调用
过程:
回到函数声明的位置
用实参给形参赋值(传参)
执行函数体
获取返回值
回到函数调用的位置
压栈:
当调用函数的时候,系统会自动在栈区间开辟空间保存函数调用过程中产生的数据(形参,函数中声明的变量)
2.返回值
看有没有遇到return,遇到了函数的返回值就是return后面的值,没有返回值就是None。
函数调用表达式的结果就是函数的返回值
3.函数的参数
位置参数和关键字参数: 位置参数要在关键字参数的前面
参数的默认值: 参数名=值
不定长参数: *参数名; **参数名
参数类型说明: 参数名:类型名
对函数的返回值进行类型说明: def 函数名(参数列表) -> 返回值类型:
4.匿名函数
函数名 = lambda 参数列表:返回值
def func1(a: int) -> int:
return a**2
func1(10)
print(func1(10))
100
02.变量的作用域
1.变量的作用域
变量在程序中能够使用的范围
2.全局变量
a.声明在函数或者类的外部的变量都是全局变量
b.全局变量是从声明开始到整个py文件结束,任何位置都可以使用(作用域:从声明开始到文件结束)
3.局部变量
a.声明在函数或者类的里面的变量都是局部变量
b.局部变量是从声明开始到函数结束,任何位置都可以使用(作用域:从声明开始到函数结束)
===========1.全局变量===========
#全局变量
a = 10
# x和y是全局变量
for x in range(10):
y = 20
print(x)
0
1
2
3
4
5
6
7
8
9
print(x, y)
9 20
if True:
# b是全局变量
b = 20
print(b)
20
def func1():
print('函数中:', a)
print('函数中', x, y)
func1()
函数中: 10
函数中 9 20
============2.局部变量=============
# num1, num2, aa, xx都是局部变量
def func2(num1, num2):
print(num1, num2)
aa = 11
print(aa)
for xx in range(5):
print(xx)
print(xx)
func2(10, 20)
# print(num1) # NameError: name 'num1' is not defined
# print(aa) # NameError: name 'aa' is not defined
11
0
1
2
3
4
4
============3.global的使用==========
global关键字只能在函数中使用,作用是在函数中声明一个全局变量
语法:
global 变量名
变量名 = 值
# 声明一个全局变量a1
a1 = 100
def test1():
# 声明一个局部变量a1
# a1 = 200
# print(a1)
global a1
a1 = 200
print(a1)
# 在函数中声明全局变量b1
global b1
b1 = 300
test1()
print(a1, b1)
200
200 300
=============4.nonlocal的使用==============
nonlocal关键字只能在函数中使用
当需要在局部的局部中修改局部变量的值,就使用nonlocal
语法:
nonlocal 变量名
变量名 = 值
def func1():
# 声明一个局部变量a2
a2 = 'abc'
# python中函数可以声明函数
def func11():
nonlocal a2
a2 = 'python'
print('func11-a2:', a2)
# a3的作用域在func11中
a3 = 111
func11()
print('func1-a2:', a2)
func1()
func11-a2: python
func1-a2: python
# 思考?
funtions = []
for x in range(5):
def func1(a):
return a*x
funtions.append(func1)
t1 = funtions[0]
t2 = funtions[2]
print(t1(2))
print(t2(2))
8
8
03.函数作为变量
python中,声明函数其实就是声明一个类型是function的变量。函数名就是变量名
函数名作为变量除了可以用来调用函数获取返回值以外,普通变量能做的它都能做
# 声明类型是int类型的变量a
a = 10
print(type(a)) # <class 'int'>
# 声明类型是dict类型的变量b
b = {'a': 12, 'b': 200}
print(type(b)) # <class 'dict'>
print(b['a']) # 12
# 声明类型是function类型的变量c
c = lambda x: x*x
print(type(c)) # <class 'function'>
c(10)
# # 声明类型是function类型的变量d
def d(x):
def e():
print('abc')
e()
return x*x
print(type(d)) # <class 'function'>
d(10) # abc
1.让一个变量给另外一个变量赋值
# 声明一个列表变量list1
list1 = [1, 2, 3]
# 使用列表变量list1给list2赋值
list2 = list1
# 将list2当成列表来用
print(list2[0]) # 1
# 声明一个函数变量func11
def func11():
print('我是函数')
# 使用函数变量func11给ff赋值
ff = func11
# 将ff当成函数来用
ff() # 我是函数
2.将变量作为列表的元素或者字典的值
# 声明列表变量list1
list1 = [100, 200, 300]
# 将列表变量list1作为列表list2的元素
list2 = [list1, 100]
print(list2[0][0]) # 100
# 声明一个函数变量func2
def func2():
print('我是函数2')
# 将函数变量func2作为列表list2的元素
list2 = [func2, 100]
print(list2[0]()) # 我是函数2
# None
3.作为函数的参数
将函数1作为实参,传递给函数2;这儿的函数2就是一个高阶函数(实参高阶函数)
def test(x):
# x = func3
print('test:', x)
if not isinstance(x, int):
x()
# 声明一个int类型的变量a
a = 10
# 将变量a作为test的实参
test(a)
# 声明一个fucntion类型的变量func3
def func3():
print('我是函数3')
test(func3)
test: 10
test: <function func3 at 0x021B5540>
我是函数3
3.1 sort函数
def sort(key=None, reverse=False)
key - 确定排序的时候以什么值为标准来排序(默认情况下,以列表的元素的大小为标准来排序);
需要传一个函数,函数需要一个参数和一个返回值。这儿的参数是列表的元素
reverse - 是否降序排序, 需要传一个bool值
# list2.sort(reverse=True)
"""
[1, 34, 20, 89, 8] -> [1, 8, 20, 34, 89]
index = 0 [1, 34, 20, 89, 8]
index = 1 [1, 8, 34 ,89, 20]
index = 2 [1, 8, 20, 89, 34]
...
"""
def yt_sort(list1, key=None):
# list1 = my_list2; key = get_age
if key == None:
# 直接对列表元素进行排序
for index in range(len(list1)):
for index2 in range(index+1, len(list1)):
current = list1[index]
behind = list1[index2]
if behind < current:
list1[index], list1[index2] = list1[index2], list1[index]
else:
for index in range(len(list1)):
for index2 in range(index+1, len(list1)):
current = key(list1[index])
behind = key(list1[index2])
if behind < current:
list1[index], list1[index2] = list1[index2], list1[index]
my_list = [1, 34, 20, 89, 8]
yt_sort(my_list)
# my_list.sort()
print(my_list)
my_list2 = [
{'name': '张三', 'age': 18},
{'name': '李四', 'age': 30},
{'name': '王五', 'age': 10}
]
# my_list2.sort() # TypeError: '<' not supported between instances of 'dict' and 'dict'
# yt_sort(my_list2) # TypeError: '<' not supported between instances of 'dict' and 'dict'
def get_age(x):
return x['age']
yt_sort(my_list2, get_age)
print(my_list2)
my_list2 = [
{'name': '张三', 'age': 18, 'score': 90},
{'name': '李四', 'age': 30, 'score': 80},
{'name': '王五', 'age': 10, 'score': 89}
]
# 取最大年龄对应的字典
max_age = max(my_list2, key=lambda x: x['age'])
print(max_age)
# 取最大成绩对应的字典
max_score = max(my_list2, key=lambda x: x['score'])
print(max_score)
test: <function func3 at 0x021B5540>
我是函数3
[1, 8, 20, 34, 89]
[{'name': '王五', 'age': 10}, {'name': '张三', 'age': 18}, {'name': '李四', 'age': 30}]
{'name': '李四', 'age': 30, 'score': 80}
{'name': '张三', 'age': 18, 'score': 90}
练习:要求将按列表中元祖的第二个元素,获取最大值。
my_list3 = [('z', 10), ('b', 30), ('c', 20)]
print(max(my_list3, key=lambda item: item[1]))
('b', 30)
4.变量作为函数的返回值
返回值是函数的函数,也叫高阶函数(返回值高阶函数)
def test2(n):
sum1 = 1
for x in range(1, n+1):
sum1 *= x
return sum1
re = test2(5) + 10
print(re)
130
def get_operation(char):
# char = '+'
"""
根据不同的符号返回不同的功能(函数功能的描述)
:param char: 运算符符号
:return: 不同运算符对应的功能的函数
"""
if char == '+':
# 求和的功能
def sum(*args, **kwargs):
# args = (10,20,30)
"""求多个数的和"""
sum1 = 0
for item1 in args:
sum1 += item1
for key in kwargs:
sum1 += kwargs[key]
print('yt')
return sum1
return sum
elif char == '*':
def mul(*args, **kwargs):
sum1 = 1
for item1 in args:
sum1 *= item1
for key in kwargs:
sum1 *= kwargs[key]
return sum1
return mul
elif char == '-':
def diff(*args):
"""求多个数的差"""
# (10, 20, 30)
sum1 = args[0]
for index in range(1, len(args)):
sum1 -= args[index]
return sum1
return diff
else:
print('暂时不支持这个运算符')
return None
# re是一个函数
re = get_operation('+')
# re(10, 20, 30) - 调用函数获取返回值
print(re(10, 20, 30)) # 60 = 10+20+30
# get_operation('*') - 这个整体是一个函数
# get_operation('*')(1, 2, 3) - 调用求乘积的那个函数,并且获取返回值
re = get_operation('*')(1, 2, 3)
print(re)
# 10 - 20 - 30
print(get_operation('-')(100, 20, 30))
yt
60
6
50
04.迭代器
1.什么是迭代器(iter)
迭代器是python中的容器类的数据类型,可以同时存储多个数据。
取迭代器中的数据只能一个一个的取,而且取出来的数据,在迭代器就不存在了
2.迭代器中数据的来源
a.将其他序列转换成迭代器
b.使用生成式、生成器去产生数据
1.将数据转换成迭代器
所有的序列都可以转换成迭代器
#将字符串转换成迭代器
iter1 = iter('abcd')
print(iter1)
iter2 = iter([1, 10, 100, 1000])
print(iter2)
iter3 = iter({'name': '小明', 'age': 20})
print(iter3)
<str_iterator object at 0x0050C310>
<list_iterator object at 0x006A38B0>
<dict_keyiterator object at 0x00697F00>
2.获取迭代器中的元素
a.
next(迭代器) / 迭代器.next() - 取出迭代器中第一个元素(已经取出来的元素再也回不到迭代器中了)
print(next(iter1))
print(next(iter1))
print(next(iter1))
print(next(iter1))
# print(next(iter1)) # 当迭代器是空的时候,使用next获取元素,会出现StopIteration异常
print(iter2.__next__())
print(next(iter2))
a
b
c
d
1
10
b.通过for循环取出迭代器中每个元素
for x in iter2:
print('==:', x)
# print(next(iter2)) # 出现异常StopIteration,因为for循环已经将这个迭代器中的元素取完了
==: 100
==: 1000
05.生成器
1.什么是生成器
生成器就是迭代器;迭代器不一定是生成器
调用带有yield关键字的函数,拿到的结果就是一个生成器。生成器中元素就是yield关键字后边的值
2.生成器怎么产生数据
只要函数中有yield关键字,调用函数不会再执行函数体获取返回值,而是创建一个生成器。
当获取生成器的元素的时候,才会执行函数的函数体,执行到yield语句为止,并且将yield后面的值作为结果返回;
并且保存当前执行的位置。
获取下一个元素的时候,就从上次结束的位置接着往下去执行函数,直到函数结束或者遇到yield为止;
如果遇到yield就将yield后面的值作为结果返回,并且保存当前执行的位置。如果函数结束了,就出现StopIteration异常
生成器对应的函数,执行完成遇到yield的次数,决定了生成器能产生的数据的个数
def func1():
print('abc')
yield 123
print('!!!!!!')
yield 100
re = func1()
print(re)
# next(re) - 执行re对应的函数的函数体,将yield关键字后边的值作为结果
print('===:', next(re))
# print('===:', next(re))
# print('===:', next(re))
<generator object func1 at 0x00537EA0>
abc
===: 123
def numbers():
for x in range(101):
yield x
print('next', x)
gener = numbers()
print(next(gener))
print(next(gener))
print(next(gener))
0
next 0
1
next 1
2
写一个生成器可以无限产生学号
def creat_id():
num = 0
while True:
yield 'stu'+str(num)
num += 1
gener_id = creat_id()
print(next(gener_id))
for x in range(10):
print(next(gener_id))
print(next(gener_id))
stu0
stu1
stu2
stu3
stu4
stu5
stu6
stu7
stu8
stu9
stu10
stu11
练习:写一个生成器,可以不断产生斐波那契数列:1,1,2,3,5,8,13,21....
def sequence(n):
pre_1 = 0
pre_2 = 1
for _ in range(n):
yield pre_2
pre_1, pre_2 = pre_2, pre_1+pre_2
gen = sequence(10)
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
for x in gen:
print('for:', x)
1
1
2
3
for: 5
for: 8
for: 13
for: 21
for: 34
for: 55
06.homework
0.写一个匿名函数,判断指定的年是否是闰年
# 闰年:能够被4整除但是不能被100整除。或者能够被400整除
isleapyear = lambda year: (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
print(isleapyear(2012))
print(isleapyear(2008))
print(isleapyear(2018))
print(isleapyear(2000))
True
True
False
True
1.写一个函数将一个指定的列表中的元素逆序( 如[1, 2, 3] -> [3, 2, 1])(注意:不要使 表自带的逆序函数)
def reverse(list1: list):
length = len(list1)
for index in range(length//2):
list1[index], list1[length-1-index] = list1[length-1-index], list1[index]
my_list = [1, 2, 3] # index = 0 list1[index] = list1[len(list1)-index-1]
reverse(my_list)
print(my_list)
[3, 2, 1]
2.写一个函数,提取出字符串中所有奇数位上的字符
def get_substr(str1: str):
strstr = ''
for index in range(len(str1)):
if index & 1:
strstr += str1[index]
return strstr
print(get_substr('abcdefg'))
bdf
3.写一个函数,统计指定列表中指定元素的个数(不用列表自带的count方法)
def get_count(list1, item):
count = 0
for x in list1:
if x == item:
count += 1
return count
print(get_count([1, 23, 3, 4, 4, 23], 4))
2
7.写一个函数,能够将指定字符串中的指定子串替换成指定的其他子串(不能使用字符串的replace方法)
例如: func1('abcdaxyz', 'a', '//') - 返回: '//bcd//xyz'
def replace(str1: str, old, new):
# 先切割
str_list = str1.split(old)
strstr = str_list[0]
for index in range(1, len(str_list)):
strstr += '+'+str_list[index]
return strstr
print(replace('abcabchasjhsabchjshdjfabcsjhdfjhabc123', 'abc', '+'))
++hasjhs+hjshdjf+sjhdfjh+123
网友评论