第十一章: - 函數 - 函數二

01. - 函數 - 返回值

(1).求任意幾個數的和

可以通過return來指定函數的返回值

def fn(*nums):

    # 定義一個變量來保存結果
    result = 0

    # 遍歷元組,並將元組中的元素累加
    for n in nums:

        result += n
    print(result)    # 10
fn(1,2,3,4)

(2). 返回值可以直接使用,也可以通過一個變量來收拾函數返回值的結果

return後面可以跟任意的對象,甚至可以是一個函數

def fn():
    # return 100           #   100
    # return [1,2,3]       #  [1, 2, 3]
    # return 1 + 1         #  2
    # return False         #  False
    def fn2():
        print('python')
    return fn2
r = fn()
r()        #  python
print(r)   #  <function fn.<locals>.fn2 at 0x0000021240783EA0>

(3).如果只寫一個return 或者 不寫return 則相當於 return None

def fn2():
    a = 10   # None
    return   # None
r = fn2()
print(r)

(4). 在函數中 return後面的代碼都不會執行,return 一旦執行函數自動結束

def fn3():
    print('hello')
    return
    print('abc')
r = fn3()
print(r)
>>>
hello
None

(5).break,continue和return的用法

def fn4():
    for i in range(5):
        if i == 3:
            # break   # 0  1  2  循環結束 # 用來退出當前循環
            # continue  # 0 1 2 4 循環結束 # 用來天廚當次循環
            return     # 0 1 2     #  用來結束函數
        print(i)
    print('循環結束')
fn4()

(6).求任意幾個數的和

可以通過return來指定函數的返回值

def fn(*nums):

    定義一個變量來保存結果
    result = 0

    遍歷元組,並將元組中的元素累加
    for n in nums:

        result += n
   # print(result) 
   return result
r = fn(1,2,3)
print(r)                     #  6
print(r + 6)          	   #  12

(7).fn5 和 fn(5)的區別:

def fn5():
    return 10

print(fn5)    # <function fn5 at 0x0000016BA2273EA0>  fn5是函數對象,實際上在打印函數對象
print(fn5())    # 10   # fn5()是在調用函數,實際上在打印fn5()函數的返回值

02. - 函數 - 文檔字符串

(1).help() 可以查詢Python 函數中的用法

語法 help(函數對象)
help(print) # 直接執行,不用打印

def fn(a:int,b:str,c:bool) -> int:         #  (-> int是想告訴別人 ,返回值是一個int類型)
    '''

    函數的參數
    :param a:  作用 ....
    :param b:  作用....
    :param c:  作用
    :return:  int
    '''
    return 10

help(fn)
>>>
Help on function fn in module __main__:

fn(a:int, b:str, c:bool) -> int
    函數的參數
    :param a:  作用 ....
    :param b:  作用....
    :param c:  作用
    :return:  int

03. - 函數 - 函數作用域

1. 作用域指的是變量生效的區域

2.在Python中有兩種作用域

(1).全局作用域:全局作用域 和 函數作用域

全局作用域在程序執行時創建,在程序結束時銷燬
所有函數以外的區域都是全局作用域
在全局作用域重定義的變量,都屬於全局變量,全局變量可以在程序中的任意位置訪問

(2).函數作用域

函數作用域在函數調用時創建,在調用結束時銷燬
函數沒調用一次就會產生一個新函數的作用域
在函數作用域中定義的變量,都是局部變量,它只能在函數內部被訪問

b = 20
def fn():

    a = 10   # a 定義在函數內部,所以它的作用域就是函數內部,函數外部都是無訪問的

    print('函數內部:','a =',a)
    print('函數內部:','b =',b)

fn()

# print('函數外部:','a =',a)
print('函數外部:','b =',b)
>>>
函數內部: a = 10
函數內部: b = 20
函數外部: b = 20

def fn2():
    a = 30
    def fn3():
        print('fn3中:','a =',a)        #  fn3中: a = 30
    fn3()
fn2()

3. global a

如果希望在函數內部修改全局變量,則需要使用global關鍵字來聲明變量

global a # 聲明在函數內部的使用 a 是全局變量,此時再去修改 a 時,就是修改全局變量

(1). global a聲明之前:

a = 20
def fn2():

    a = 10
    print('函數內部','a =',a)

fn2()
print('函數外部:','a =',a)
>>>
函數內部 a = 10
函數外部: a = 20

(2). global a聲明之後:

a = 20
def fn2():
	# 如果希望在函數內部修改全局變量,則需要使用global關鍵字來聲明變量
    global a  # 聲明在函數內部的使用 a 是全局變量,此時再去修改 a 時,就是修改全局變量
    a = 10
    print('函數內部','a =',a)

fn2()
print('函數外部:','a =',a)
>>>
函數內部 a = 10
函數外部: a = 10

04. - 函數 - 命名空間

(1).命名空間實際上就是一個字典,是一個專門用來存儲變量的字典

locals()用來獲取當前作用域的命名空間

如果在全局作用域中調用locals()函數,則獲取全局作用域命名空間,如果在函數作用域中調用locals(),則獲取函數命名空間

返回的就是一個字典(Dict)

1.函數外部的命名空間:

a = 30
b = 40
s = locals()  # 獲取當前的命名空間
print(s)
print(a)
print(s['a'])
s['c'] = 200   # 在命名空間中添加一個變量 c
print(s)
>>>
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000020D5E4AC128>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/軟件安裝包/pyCharm 文件 項目/Demon1.py', '__cached__': None, 'a': 30, 'b': 40, 's': {...}}
30
30
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000020D5E4AC128>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/軟件安裝包/pyCharm 文件 項目/Demon1.py', '__cached__': None, 'a': 30, 'b': 40, 's': {...}, 'c': 200}

2.函數內部的命名空間:

def fn4():
    a = 10        # 定義一個變量,把 10 賦值給 a
    s = locals()  # 在函數內部調用locals()會獲取函數的命名空間
    s['b'] = 20   # 可以通過 s 來操作函數的命名空間,但是不建議這麼做(自己的理解:也可以利用命名空間定義一個變量 b)
    print(s['b']) # 20
    print(s)      # {'a': 10, 'b': 20}

fn4()

05. - 函數 - 遞歸

1.嘗試求出10的階乘(10!)

1! = 1
2! = 12 = 2
3! = 1
23 = 6
4! = 1
234 = 24

print(1*2*3*4*5*6*7*8*9*10)          #  3628800

n = 10
for i in range(1,10):
   n *= i
print(n)                                       #  3628800

2. 創建一個函數求任意數的階乘.

def fn(n):

    # 創建一個變量,來接收結果
    result = n

    for i in range(1,n):
        result *= i

    return result
print(fn(10))          #  3628800

3.遞歸式的函數

遞歸簡單理解就是自己去調用自己
遞歸式函數就是在函數中調用自己

這個是無窮遞歸函數的函數語法格式:
def fn2():

    fn2()
fn2()

4.遞歸是解決問題的一種方式

遞歸式函數的兩個條件:

(1).基線條件

問題可以被分解成最小的問題,當滿足基線條件時,遞歸補在執行了

(2).遞歸條件

將問題繼續分解的條件
4! = 1234 = 24 # 4 * 3!
3! = 1
23 = 6 # 3 * 2!
2! = 1
2 = 2 # 2 * 1!
1! = 1

def fn2(n):

    # 基線條件
    if n == 1:

    # 1的階乘是它本身
        return 1

    # 遞歸條件
    return n * fn2(n-1)

print(fn2(10))
>>>
3628800

06. - 函數 - 遞歸練習

1. 練習一: 創建一個函數 來爲任意數做任意冪運算

24 = 222*2 = 16
2
3 = 222 = 8
22 = 2*2 = 4
2
1 = 2

def fn4(n,i):

    # 定義了一個函數,其中有2個參數,n 要做冪運算的底數, i 做冪運算的指數
    # 基線條件 冪爲1
    if i == 1:

        # 當i = 1 時,返回它本身
        return n

    # 遞歸條件  2*2*2*2 = 16  2**4
    return n * fn4(n,i - 1)   # return n ** i  也可以

print(fn4(9,9))

2.練習二:創建一個函數,用來檢查任意的字符串是否是迴文字符串,如果是返回 True,不是返回 False

迴文字符串,字符串從後往前念和從前往後念是一樣的 : abcba
判斷 abcdefgfedcba 是否是迴文字符串

先檢查第一個字符和最後一個是否一致,如果不一致就不是迴文字符串
如果一致,則看剩餘部分是否是迴文字符串
檢查 bcdefgfedcb 是不是迴文字符串
檢查 cdefgfedc 是不是迴文字符串
檢查 defgfed 是不是迴文字符串
檢查 efgfe 是不是迴文字符串
檢查 fgf 是不是迴文字符串
檢查 g 是不是迴文字符串


def fn5(s):
    # 這個函數就是檢查任意一個字符串是否是迴文字符串
    # 參數 s 就是我們要檢查的字符串

    # 基線條件
    if len(s) < 2:

        # 字符串的長度小於 2 ,則這個字符串一定是迴文字符串
        return True

    elif s[0] != s[-1]:

        # 第一個字符和最後一個字符不相等,則不是迴文字符串
        return False

    # 遞歸條件
    return fn5(s[1:-1])

print(fn5('bcdefgfedcb'))      #  True
print(fn5('b1551b'))             #  True
print(fn5('1'))                       #  True
print(fn5(''))                         #   True  
 這個是空字符串,也是個迴文字符串

07. - 函數 - 高級函數

特點:

1.接收一個或多個函數作爲參數
2.將函數作爲返回值返回

以上兩點滿足任意一個特點就是高級函數

(1).原方案


# 定義一個函數 可以將指定列表當中的所有偶數,保存到一個新的列表中返回
l = [1,2,3,4,5,6,7,8,9,10]

# 定義一個函數

def fn(lst):

    # 創建一個新的列表
    new_list = []

    for n in lst:

        # 判斷 n 的奇偶
        if n % 2 == 0:
            new_list.append(n)

    # 返回新的列表
    return new_list

print(fn(l))   #   [2, 4, 6, 8, 10]

(2).改進後的方案一:

定義一個函數 可以將指定列表當中的所有偶數,保存到一個新的列表中返回
l = [1,2,3,4,5,6,7,8,9,10]

# 定義一個函數


def fn(lst):    # 傳一個變量 n

    # 定義一個函數,用來檢測一個任意的偶數
    def fn2(i):

        if i % 2 == 0:
            return True

    # 創建一個新的列表
    new_list = []

    for n in lst:

        # 判斷 n 的奇偶
        if not fn2(n):
            new_list.append(n)

    # 返回新的列表
    return new_list

print(fn(l))   #   [1, 3, 5, 7, 9]

(3).改進後的方案二:

# 改進後的方案二:
# 定義一個函數 可以將指定列表當中的所有偶數,保存到一個新的列表中返回
l = [1,2,3,4,5,6,7,8,9,10]

# 定義一個函數
def fn(lst):    # 傳一個變量 n

    # 定義一個函數,用來檢測一個任意的偶數
    def fn2(i):

        if i % 2 == 0:
            return True

    # 定義一個函數,用來檢測指定數字是否大於5
    def fn3(i):

        if i > 5:
            return True
        return False


    # 創建一個新的列表
    new_list = []

    for n in lst:

        # 判斷 n 的奇偶
        # if not fn2(n):       # [2, 4, 6, 8, 10]
        if fn3(n):             # [6, 7, 8, 9, 10]
            new_list.append(n)

    # 返回新的列表
    return new_list

print(fn(l))   #   [1, 3, 5, 7, 9]

(4).改進後的方案三:當我們使用一個函數作爲參數時,實際上是將指定的代碼(一段程序或者說是一個函數)傳遞進了目標函數


# 改進後的方三:
# 定義一個函數 可以將指定列表當中的所有偶數,保存到一個新的列表中返回
l = [1,2,3,4,5,6,7,8,9,10]

# 定義一個函數,用來檢測一個任意的偶數
def fn2(i):
    if i % 2 == 0:
        return True

# 定義一個函數,用來檢測指定數字是否大於5
def fn3(i):
    if i > 5:
        return True
    return False

# 創建一個新的列表
new_list = []

# 定義一個函數
def fn4(i):

    if i % 3 == 0:
        return True
    return False

def fn(func,lst):    # 傳一個變量 n

    for n in lst:

        # 判斷 n 的奇偶
        # if not fn2(n):       # [2, 4, 6, 8, 10]
        # if fn3(n):           # [6, 7, 8, 9, 10]
        if func(n):            # [2, 4, 6, 8, 10]
            new_list.append(n)

    # 返回新的列表
    return new_list

print(fn(fn2,l))   #  [2, 4, 6, 8, 10]      # fn2 在這裏是在傳對象,而不是在調用函數
print(fn(fn3,l))   #  [6, 7, 8, 9, 10]
print(fn(fn4,l))   #  [3, 6, 9]
# 當我們使用一個函數作爲參數時,實際上是將指定的代碼(一段程序或者說是一個函數)傳遞進了目標函數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章