day11 函數進階

1.什么是返回值

"""
返回值是從函數里面傳遞到函數外面的數據

  1. 怎么返回數據
    返回值就是 return 關鍵字后面的表達式的值

語法:
return 表達式1,表達式2,....

說明:
return - 關鍵字,只能出現在函數體中
a.將數據從函數內容扔到函數的外部 b. 結束函數(執行函數的時候只要遇到return函數直接結束)

表達式 - 可以一個都沒有(相當于 None),可以有一個(返回值就是指定數據),也可以有多個(本質返回的是一個元組)

注意: 如果一個函數中沒有return(或者執行函數體的時候沒有遇到 return)那么這個函數的返回值就是 None

  1. 怎么在外部使用返回值返回的數據
    返回值就是函數調用表達式的值

"""

2.什么時候需要返回值(初學者)

"""
看實現函數的功能會不會產生新的數據,如果產生了新的數據,就將新的數據作為返回值返回
"""

def yt_sum(n):
# n = 5
sum1 = 0
for x in range(n+1):
sum1 += x
# print(sum1)
# return None
return sum1

普通數據能做的事情函數調用表達式都可以做

a = 10

a = yt_sum(10)
print('a:', a)

print(10)

print(yt_sum(10))

print(10 * 2)

print(yt_sum(10) * 2)

list1 = [10, 20, 30]

list1 = [yt_sum(10), 20, 30]
print(list1)

def fun1():
return [1, 2, 3]

print(fun1()[1]) # print([1, 2, 3][1])

3. 函數調用過程(非常重要!)

"""
第一步:回到函數定義的位置
第二步:傳參(用實參給形參賦值;傳參的時候必須保證每個參數都有值)
第三步:執行函數體
第四步:執行完函數體(a.執行完函數體中的最后一條語句 b.遇到了return),確定函數返回值(看執行完函數體有沒有遇到return,如果遇到了函數的返回值就是return后面的值,否則是 None)
第五步:回到函數調用的位置接著往后執行(這個時候函數調用表達式的值就是函數的返回值)
"""
print('=======')

print(sum1)

print(yt_sum(5)) # 15
print('+++++++')

print(sum1)

1. 函數調用過程中內存的變化

"""
每次在調用函數的時候,系統會自動為這個函數創建一個獨立的棧區間,用來保存函數運行過程中產生的數據(函數的參數;函數中聲明的變量);當函數調用結束后這個棧區間會自動銷毀。(壓棧)
"""

2.全局變量和局部變量

"""
1)全局變量
沒有定義在函數里面或者類里面的變量就是全局變量

作用域:從定義開始到程序結束的任何位置都可以使用
"""

變量 a 是全局變量

a = 10

print(a)

for _ in range(5):
print('循環中:', a)

def func1():
print('函數中:', a)

func1()

變量b、c都是全局變量

for b in range(5):
c = 10
print('b循環中', b, c)

print('b循環外:', b, c)

def func2():
print('b函數中:', b, c)

func2()

"""

  1. 局部變量
    定義在函數中的變量就是局部變量(形參是局部變量,注意:定義函數的時候給形參賦的默認值其實是保存在堆里面的)

作用域:從定義開始到函數結束的任何位置都可以使用
"""

def func3():
# 變量x是局部變量
x = 100
print(x)
for _ in range(3):
print('x2:', x)

func3()

print(x) # NameError: name 'x' is not defined

面試題:問以下程序結束后打印結果是多少

def func3(list1=[10, 20, 30]):
# list1 = [10, 20, 30]
list1.append(100) # list1 = [10, 20, 30, 100]
return list1

scores = func3() # scores = [10, 20, 30, 100]
scores = func3() # scores = [10, 20, 30, 100]
print(scores) # [10, 20, 30, 100, 100]

3. global 和 nonlocal

"""

  1. global:在函數中聲明指定的變量是全局變量
    作用:a. 在函數中修改全局變量的值 b. 在函數中定義一個全局變量
    注意:聲明必須放在使用變量前
    """

name = '張三'

def change():
# 在函數中修改全局變量name的值
global name

print(name)
name = '李四'

# 在函數中定義全局變量 age
global age
age = 18

change()
print(name)
print(age)

"""

  1. nonlocal(了解)
    如果希望在局部的局部中去修改局部變量的值,就可以用 nonlocal 進行說明
    """

def func4():
m = 100

def func5():
    nonlocal m
    m = 200
    print('m1:', m)

func5()
print('m2:', m)

func4()

1. 什么是匿名函數

"""
匿名函數本質還是函數,普通函數中除了定義的語法其他全部適用于匿名函數

1)定義匿名函數的語法:
函數名 = lambda 形參列表:返回值

說明:
lambda - 關鍵字,固定寫法
形參列表 - '形參1,形參2,...' 的形式存在
: - 固定寫法
返回值 - 寫任何有結果的表達式

2)調用匿名函數: 函數變量(實參列表)
匿名函數的本質就是類型是function的數據, 普通數據能做的它都可以做
"""

定義一個匿名函數求兩個數的和

x = lambda num1, num2: num1+num2 # function

"""
def x(num1, num2):
return num1 + num2
"""

a = 10 # int
b = 'abc' # str
c = [10, 20, 30] # list
d= {'a': 230, 'b': 100} # dict

調用匿名函數

print(x(100, 200))

list1 = [10, 'abc', lambda num1, num2: num1+num2]
print(list1[0] + 10 - 100)
print(list1[1].join(['10', '20', '30']))
print(list1[2](1, 3)) # 4

練習1: 寫一個匿名函數用來判斷指定的年齡是否成年,根據情況返回 True/False

is_adult = lambda age: '成年' if age >= 18 else '未成年'
print(is_adult(87))

1.什么是遞歸函數

"""
在函數內調用函數本身的函數就是遞歸函數(自己調用自己)

循環能做的事情遞歸都可以做
"""

func1就是遞歸

def func1():
print('函數1')
func1()

func1()

2.怎么使用遞歸

"""
第一步:確定臨界值(在臨界值的位置結束函數)
第二步:找關系(找當次循環(f(n))和上一次循環(f(n-1))之間的關系)
第三步:假設函數的功能已經實現,用f(n-1)去實現f(n)的功能
"""

寫一個遞歸函數:計算1+2+3+4+..+n

f(n) = 1+2+3+4+..+n-1+n

f(n-1) = 1+2+3+4+...+n-1

def yt_sum(n):
# 1.找臨界值
if n == 1:
return 1

# 2.關系: yt_sum(n) = yt_sum(n-1)+n
return yt_sum(n-1) + n

print(yt_sum(100))

def yt_sum(n):
sum1 = 0
for x in range(n+1):
sum1 += x
return sum1

2.用遞歸計算斐波那契數列第20個數:1,1,2,3,5,8,13,21,34,...

def series(n):
# 1.找臨界值
if n == 1 or n == 2:
return 1
# 2.找關系: series(n) = series(n-1) + series(n-2)
return series(n-1) + series(n-2)

print(series(5)) # print(5)

"""
def series(n):
print(series(5))
series(5): n=5; if 5==1 or 5==2; return 3 + 2
series(4): n=4; if 4==1 or 4==2; return 2 + 1 == 3
series(3): n=3; if 3==1 or 3==2; return 1 + 1 -> return 2
series(2): n=2; if 2==1 or 2==2; return 1
series(1): n=1; if 1==1 or 1==2; return 1
series(2): n=2; if 1==1 or 2==2; return 1
series(3): n=3; if 3==1 or 3==2; 1 + 1 == 2
series(2): return 1
series(1): return 1
"""

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。