Python零基礎入門學習筆記(二)

2020-10-22 15:00:46

Python 基礎入門學習

三.函數

  1. 函數

    def 函數名(引數):

    **""" 說明檔案內容 """**
    
    **程式碼1**
    
    **程式碼2**
    
    **.......**
    

    注意:引數可有可無,必須先定義後使用

    函數中return之後的程式碼並不會執行

    help(函數名) 檢視函數解釋說明的資訊

  2. 函數(二)

    區域性變數:只在函數體內部生效的變數

    全域性變數:指在函數體內、外都能生效的變數

    在函數體內部修改全域性變數:在函數體內部用 global 宣告變數為全域性變數後修改

    函數有多個返回值時: return 後面可以直接書寫 元組、列表、字典,返回多個值

    位置引數:呼叫函數時根據函數定義的引數位置來傳遞引數,傳遞和定義引數的順序及個數必須一致

    關鍵字引數:函數呼叫時,通過「鍵=值」的形式加以指定傳參,關鍵字引數之間不存在先後順序

    預設引數:也叫預設引數,用於在定義函數時為引數提供預設值,呼叫函數時可以不傳入有預設值的引數。在定義和呼叫函數時,位置引數必須在預設引數之前

    不定長引數:也叫可變引數,用於不確定呼叫時會傳遞多少個引數的場景,可用 包裹位置引數 或 包裹關鍵字引數 來進行引數傳遞

    包裹位置傳遞(元組):

    def 函數名( *args ): 
        print( args )
    
    函數名( 'abc' , 123 )
    

    包裹關鍵字傳遞(字典):

    def 函數名( **kwargs): 
        print( kwargs )
        
    函數名( a = 'abc' , b = 123)
    

    包裹位置傳遞和包裹關鍵字傳遞都是一個組包的過程,即收集零散資料並組成一個元組或字典

    返回值拆包

    元組: return 10, 20 num1, num2 = 函數 即得到num1 = 10 , num2 = 20

    字典: 對字典拆包,得到的是字典的key

  3. 交換變數值

    方法一:藉助第三變數儲存資料

    方法二: a, b = b, a

  4. 參照: 在python中,值是靠參照來傳遞的

    可以用 id() 來判斷兩個變數是否為同一個值的參照。可以將id理解為那塊記憶體的地址標識。

  5. 可變型別與不可變型別

    可變型別:列表(list)、字典(dict)、集合(set)

    不可變型別:整型、浮點型、字串、元組

  6. 函數加強應用—學員管理系統

    #定義功能介面函數
    def print_info():
        """函數功能介面"""
        print('---select---')
        print('1.add')
        print('2.delete')
        print('3.modify')
        print('4.query')
        print('5.show all')
        print('6.exit')
        print('----end----')
    
    #定義列表等待儲存學員資訊
    info = []
    
    #新增學員資訊函數
    def add_info():
        """學員新增函數"""
        new_name = input('input name:')
        new_id = input('input id:')
        new_tel = input('input telephone:')
    
        global info
    
        for i in info:
            if new_name == i['name']:
                print('name exists!')
                #return 退出當前函數,不執行下面新增資訊的程式碼
                return
    
        info_dict = {}
        info_dict['name'] = new_name
        info_dict['id'] = new_id
        info_dict['tel'] = new_tel
        info.append(info_dict)
        print('add successful!')
    
    #刪除學員資訊
    def del_info():
        """學員刪除函數"""
        del_name = input('input name:')
    
        global info
    
        for i in info:
            if del_name == i['name']:
                info.remove(i)
                print('delete successful!')
                break
        else:
            print('name does not exist!')
    
    #修改學員資訊
    def modify_info():
        """學員資訊修改函數"""
        modify_name = input('input name:')
    
        global info
    
        for i in info:
            if modify_name == i['name']:
                i['tel'] = input('input new telephone:')
                print('modify successful!')
                break
        else:
            print('name does not exist!')
    
    
    #查詢學員資訊
    def search_info():
        """查詢資訊函數"""
        search_name = input('input name:')
    
        global info
    
        for i in info:
            if search_name == i['name']:
                print('---Message---')
                print(f"The name is {i['name']}, The id is {i['id']}, The telephone is {i['tel']}。")
                break
        else:
            print('name does not exist!')
    
    #展示所有學員資訊函數
    def showall_info():
        """展示資訊函數"""
        print('name\tid\ttelephone')
    
        global info
    
        for i in info:
            print(f"{i['name']}\t{i['id']}\t{i['tel']}")
    
    while True:
        #1.顯示功能介面
        print_info()
    
        #2.使用者輸入功能序號
        user_num = int(input('your choice:'))
    
        #3.按照使用者輸入的功能序號,執行不同的功能(函數)
        if user_num == 1:
            add_info()
    
        elif user_num == 2:
            del_info()
    
        elif user_num == 3:
            modify_info()
    
        elif user_num == 4:
            search_info()
    
        elif user_num == 5:
            showall_info()
    
        elif user_num == 6:
            exit_flag = input('are you sure? Y/N')
            if exit_flag == 'Y':
                break
        else:
            print('Error!')
    
  7. 遞迴

    特點: 函數內部自己呼叫自己、必須有出口。

    #遞迴函數求1~n的累加和
    def num(n):
        #出口
        if n == 1:
            return 1
        #函數內部自己呼叫自己
        return n+num(n-1)
    

    若沒有出口,則報錯提示超出最大遞迴深度(996)。

  8. lambda表示式(匿名函數)

    應用場景: 化簡程式碼。如果一個函數只有一個返回值,並且只有一句程式碼,可以使用lambda簡化。

    lambda 參數列: 表示式
    

    lambda表示式的參數列可有可無,函數的引數在lambda表示式中完全適用。

    lambda表示式能夠接收任何數量的引數但只能返回一個表示式的值。

    #計算 a+b 的lambda實現
    fn = lambda a,b: a+b
    print(fn(1,2))
    #輸出結果: 3
    

    lambda的引數形式:無參、有參、預設引數(預設)、可變引數*args、可變引數**kwargs。

    #無參
    fn1 = lambda : 100
    
    #有參
    fn2 = lambda a: a
    
    #預設引數
    fn3 = lambda a,b,c=100: a+b+c
    
    #可變引數 *args(元組)
    fn4 = lambda *args: args
    
    #可變引數 *kwargs(字典)
    fn5 = lambda **kwargs: kwargs
    

    lambda的應用

    #1.帶判斷的lambda
    fn1 = lambda a,b: a if a>b else b  #兩個數比大小
    
    fn2 = lambda n: n+fn2(n-1) if n != 1 else 1  #遞迴求1~n的累加和
    
    
    #2.列表資料按字典key的值排序
    students = [
        {'name':'Tom','age':19},
        {'name':'Alice','age':20},
        {'name':'Hack','age':18}
    ]
    
    students.sort(key=lambda n: n['name'])  #按照名字首字母升序排序
    
    students.sort(key=lambda n: n['age'], reverse=True)  #按照年齡降序排序
    
    
  9. 高階函數

    函數作為引數傳入,這樣的函數稱為高階函數(即複合函數)。

    測試用到的小函數:

    abs():對數位求絕對值

    round():對數位進行四捨五入

    def sum(a, b, f):
        return f(a)+f(b)
    
    result1 = sum(3.14, -2.8, abs)
    result2 = sum(3.14, -2.8, round)
    
    #lambda表示式改寫
    sum = lambda a,b,f: f(a)+f(b)
    

    Python內建高階函數: map()、reduce()、filter()。

    map(func, list) :將傳入的函數變數func作用到列表變數list中的每個元素中,並將結果組成新的列表(python2)/迭代器(python3)返回。

    #計算list1序列中各個數位的三次方
    list1 = [1,2,3,4,5]
    
    def func(x):
        return x ** 3
    
    result = map(func, list1) #此時result為map返回的迭代器
    print(result)  #將返回迭代器result的地址
    print(list(result))  #[1, 8, 27, 64, 125]
    

    reduce(func, list):functools模組中的一個高階函數,其中func必須有兩個引數。每次func結算的結果繼續和序列的下一個元素做累積計算

    #計算list2序列中各個數位的累加和
    import functools  #匯入模組
    
    list2 = [1,2,3,4,5]
    
    def func(a,b):
        return a+b
    
    result = functools.reduce(func,list2)
    
    print(result)  #15
    

    filter(func, list):用於過濾序列,過濾掉不符合條件的元素,並返回一個filter物件。可用 list() 轉換為列表。

    #過濾list3序列中所有的偶數,只留下奇數
    list3 = [1,2,3,4,5,6,7,8,9]
    
    def func(x):
        return x%2 != 0
    
    result = filter(func,list3)
    
    result = list(result)
    print(result)  #[1,3,5,7,9]
    

四.檔案操作

  1. 檔案操作

    作用:把一些內容(資料)儲存存放起來,可以讓程式下一次執行的時候直接使用,而不必重新制作一份,省時省力。

    檔案操作步驟:開啟檔案、讀寫等操作、關閉檔案。

    open():開啟一個已經存在的檔案,或建立一個新檔案。

    f = open(name, mode)
    
    #name: 是要開啟的目標檔名的字串(可以包含檔案所在的具體路徑)
    #mode: 設定開啟檔案的模式(存取模式):唯讀、寫入、追加等
    #此時f為name檔案的檔案物件,可通過f執行之後的讀寫等操作
    
    主存取模式描述
    r以唯讀方式開啟檔案。檔案的指標將會放在檔案的開頭。這是預設模式(存取模式未指定時,即為唯讀模式)。
    w開啟一個檔案只用於寫入。如果該檔案已存在則開啟檔案,並從開頭開始編輯,即原有內容會被刪除。如果該檔案不存在,建立新檔案。
    a開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該檔案不存在,建立新檔案進行寫入。
    (b)以二進位制形式讀取
    (+)可讀可寫

    存取模式r+、w+、a+的區別

    r+ :沒有該檔案則報錯,檔案指標在開頭故能讀取資料

    w+ :沒有該檔案會新建,檔案指標在開頭並會用新內容覆蓋原有內容,故無法讀取檔案內原有的資料

    a+ :沒有該檔案會新建,檔案指標在結尾故不能讀取資料

    寫入內容:write()

    檔案物件.write('內容')
    

    讀取內容:read()、readlines()、readline()。

    檔案物件.read(num)
    #num 表示要從檔案中讀取的資料的長度。不寫則預設讀取所有資料。其中換行符'\n'會佔一位
    
    檔案物件.readnlines()
    #按照行的方式把整個檔案的內容進行一次性讀取,並返回一個列表,其中每一行資料為一個元素
    
    檔案物件.readline()
    #一次讀取一行內容、重複呼叫readline()則依次讀取檔案中每一行的內容
    

    移動檔案指標:seek()

    檔案物件.seek(偏移量,起始位置)
    
    #起始位置引數: 0開頭 1當前 2結尾
    

    應用:

    #使用 a 存取模式開啟檔案,通過改變檔案指標位置來讀取資料
    f = open('test.txt','a')
    
    f.seek(0,0)  #此時可簡寫為 f.seek(0)
    con = f.read()
    
    f.close()
    
  2. 檔案備份案例

    #使用者輸入當前目錄下任意檔名,程式完成對該檔案的備份功功能(備份檔名為 xx[備份].字尾)
    
    #1.接收使用者輸入的檔名
    old_name = input('input yoru backup file name:')
    
    #2.規劃備份檔名
    index = old_name.rfind('.')  #檔名中'.'的位置
    if index > 0:  #判斷檔名,防止出現'.txt'類的無效檔名
        postfix = old_name[index:]
    
    new_name = old_name[:index] + '[備份]' + postfix  #利用字串的切片重新規劃備份檔名
    
    #3.備份檔案寫入資料
    old_f = open(old_name,'rb')
    new_f = open(new_name,'wb')
    
    while True:  #迴圈讀取,防止檔案過大時卡死
        con = old_f.read(1024)
        if len(con) == 0:  #讀取完成時
            break
        new_f.write(con)
    
    new_f.close()
    old_f.close()
    
  3. 檔案和資料夾的操作

    模組:使用 os 模組

    import os
    
    #1.檔案操作
    #檔案重新命名,也可以重新命名資料夾
    os.rename(目標檔名或路徑, 新檔名)
    
    #檔案刪除,也可以刪除資料夾
    os.remove(目標檔名)
    
    #2.資料夾操作
    #建立資料夾
    os.mkdir(資料夾名字)
    
    #刪除資料夾
    os.rmdir(資料夾名字)
    
    #3.目錄操作
    #獲取當前目錄
    os.getcwd()
    
    #改變當前預設目錄
    os.chdir(目錄資料夾)
    
    #獲取目錄列表
    os.listdir(目錄資料夾)
    
  4. 檔案和資料夾操作應用案例

     #批次修改檔名,既可新增指定字串,又能刪除指定字串
    
    import os
    
    #構造條件資料
    flag = input('輸入操作型別(1為新增,2為刪除):')
    
    #構造指定字串
    str = input('請輸入指定字串:')
    
    #找到所有檔案
    file_list = os.listdir()
    
    #新增或刪除指定字串
    for i in file_list:
        if flag == '1':
            new_name = str + i
        elif flag == '2':
            num = len(str)
            new_name = i[num:]
        else:
            print('操作模式輸入錯誤!')
            break
        #重新命名
        os.rename(i, new_name)