1. 程式人生 > 其它 >Python基礎 1.6 進階與強化

Python基礎 1.6 進階與強化

技術標籤:Python基礎python

1.6 進階與強化

文章目錄

1.6.1 組包與拆包(重要)

1.組包

​ 把多個數據變成一個,實際上以前賦值的時候就可以直接學到,只是沒提,在等號右邊放置多個數據,就能自動包裝成元組。

from_key = 2, 5, 7, 8, 9
print(from_key, type(from_key))
輸出
(2, 5, 7, 8, 9) <class 'tuple'>

2.拆包

​ 相反地,如果左邊變數數量是多個,則可以拆分右邊對應容器的元素,但是謹記,變數數量必須等於元素數量,否則會報錯,可以拆元組,列表,字典。

li = ["a", "b", "c", "d", 7]
a, b, c, d, e = li
print(a, b, c, d, e, type(a), type(e)
) 輸出 a b c d 7 <class 'str'> <class 'int'>

上述為列表,元組拆分同理,但是字典略有不同,因為字典是鍵與鍵值對應的容器,如果用相同方法去拆分的話,拆出來的只有鍵。

dict01 = {"name": "tom", "age": 17, "sex": "female"}
a, b, c = dict01
print(a, b, c, type(a))
輸出
name age sex <class 'str'>

如果想訪問鍵值

print(a, dict01[a])
print(b, dict01[b])
print(c, dict01[c])
# 或者
for k, v in dict01.items():
    print(k, v)
# 實際上 k, v 這一步就是拆包了,本來 in dict.items()所獲得的是多個元組,此步等於拆包了元組。

3 組包與拆包的應用

1.交換變數的值

一般情況下我們要交換變數,一般都需要用一個輔助變數。

a = 10
b = 20
c = 0
c = a
a = b
b = c
print(a,b)
# 輸出
20,10

而利用組包拆包,我們只要一步,

a = 10
b = 20
a, b = b, a
print(a,b)

2. 函式可以返回多個數,亦可以直接分配給多個變數

def fun_pack(num1,num2,num3):
    num_sum = num1 + num2 + num3
    num_ave = num_sum/3
    return num_sum, num_ave


num_sum, num_ave = fun_pack(88, 98, 99)
print(num_sum, num_ave)

1.6.2 引用

1.引用

​ 給一個變數賦值的時候,我們就把一個數值所在的記憶體地址,引用給了變數。我們可以用id()這個函式來檢視每個變數引用的資料的地址。

2.引用指向改變

​ 具體可以檢視1.2變數和簡單資料型別

3.函式傳參是引用傳遞

def fun_id(num):
    print("函式呼叫的時候", id(num))


a = 10
print("函式呼叫前", id(a))
fun_id(a)
print("函式呼叫後", id(a))

輸出

函式呼叫前 140708111845312
函式呼叫的時候 140708111845312
函式呼叫後 140708111845312

1.6.3 可變型別與不可變型別

​ 可變型別:在儲存空間裡可以直接修改的資料型別,在地址不變的情況下可以修改內容

  • 列表(list)
  • 字典(dict)
  • 集合(set)

​ 不可變型別:在儲存空間裡不可以直接修改的資料型別,在地址不變的情況下不可修改內容

  • 數值型別 int, bool, float
  • 字串 str
  • 元組 tuple
li = [1, 2, 3, 4]
print("改變之前的地址", id(li))
li[0] = 5
print("改變之後的地址", id(li))
a = 5
print("改變之前的地址", id(a))
a = 6
print("改變之後的地址", id(a))
str_001 = "hello world"
print("改變之前的地址:", id(str_001))
str_001 = str_001.upper()
print("改變之後的地址:", id(str_001))

輸出

改變之前的地址 2046831353408
改變之後的地址 2046831353408
改變之前的地址 140708111845152
改變之後的地址 140708111845184
改變之前的地址: 3060999261744
改變之後的地址: 3060999259760

可以看到 字串和整數在經過所謂的修改,實際上已經引向了新的地址,並不是原來的地址了。

注意,可變型別的,傳遞進入函式的時候,我們引用的依舊是這個地址。

這個時候,只要我們不重新宣告變數,此時引用的就是外面的全域性變數,不用宣告也可以對其進行更改,但是一旦只要進行了變數賦值,就會有所改變,此時函式裡的變數會變成區域性變數,不會影響到外面的變數指向的值。

def cha_dict(list_01):
    print(id(list_01))
    list_01 = [1, 2, 3, 4, 5, 6]
    print(id(list_01))
    return list_01


a = [1, 2, 3, 4]
print(id(a))
char_dict(a)
print(a)
cha_dict(a)
print(id(a))
print(a)
輸出
1675900223552
1675900223552
1675900223552
[1, 2, 3, 4, 5]
1675900223552
1675899165760
1675900223552
[1, 2, 3, 4, 5]

,可以看出只要沒進行重新賦值,我們通過函式可以直接改變可變型別的引向的值,地址不變。其他的可變型別與不可變型別同理。

def char_str(str_01):
    print(id(str_01))
    str_01 += "002"
    print(id(str_01))
    return str_01


def cha_str(str_01):
    print(id(str_01))
    str_01 = "001002"
    print(id(str_01))
    return str_01


a = "001"
print(id(a))
char_str(a)
print(a)
cha_str(a)
print(id(a))
print(a)

輸出
2257338010608
2257338010608
2257338010928
001
2257338010608
2257338010544
2257338010608
001

可以看出,其實有個很好判斷的認識,任何不可變變數,當你想要獲得改變或者刪除的內容的時候,我們都要重新使用賦值這個來引出結果,此時獲得的就是新的地址,但是在函式裡,確實會獲得新地址,卻也同時變成了區域性變數。

1.6.4 列表推導式

​ 快速生成列表的表達形式,通過for新增元素的簡潔寫法。

類似切片,但是不能省略結束。

for in range(開始位置,結束位置,步長)

new_list = []
for i in range(5):
	new_list.append(i)

print(new_list)


new_list2 = [i for i in range(5)]
new_list3 = [i for i in range(101) if i % 2 ==0]
new_list3 = [i*2 for i in range(101) if i % 2 ==0]

格式
[i(可進行計算) for i in range(範圍+步長) if 判斷]

1.6.5 匿名函式

​ 匿名函式是簡單函式的簡潔寫法,定義的函式沒有名字。

lambda [形參1][形參2]````:[單行表示式] 或者函式呼叫

lambda主體是一個表示式,僅能在表示式裡封裝有限的邏輯,不能封裝while,for迴圈。

lambda有自己的名稱空間,且不能訪問引數列表以外的引數。

lambda裡不需要return,lambda自身表示式的結果就是函式返回結果,不可以不返回。如果想返回None得自己寫None在表示式裡。如果表示式裡的函式沒返回值的時候也是none

# 有引數有返回值的匿名函式,直接呼叫
ret = (lambda a, b: (a-b)*(a+b))(5, 4)
print(ret)

# 先給匿名函式命名再傳參,有返回值
ave_grade = lambda chinese_grade, math_grade, english_grade: (chinese_grade + math_grade + english_grade) / 3
print("小明同學的考試平均分為:", ave_grade(98, 78, 100))
print("小花同學的考試平均分為:", ave_grade(95, 99, 90))

擴充套件

函式的引數是作為函式使用 匿名函式的應用

def foo(fn):
    fn()
    print(fn())


foo((lambda: 10 - 2))
# 可以看到foo函式的引數是函式,而我們此時可以快速的使用匿名函式進去被呼叫。

1.6.6 遞迴函式

​ 如果一個函式在內部呼叫其本身,這個函式就是遞迴函式。

遞迴函式一般會在特定情況下不在呼叫函式本身(防止記憶體溢位),會提前給你報錯,超出最大遞迴深度。正常情況下一定要有一個可以出口的點。

1.用遞迴函式做一個階乘

def fun_factorial(n):
    if n == 1:
        return 1
    else:
        ret = n * fun_factorial(n - 1)
        return ret


ret_10 = fun_factorial(10)
print("10的階乘結果是:", ret_10)

輸出

10的階乘結果是: 3628800

1.6.7 enumerate del

1.enumerate

​ 通過配合for遍歷容器的同時獲取元素的索引位置,元素本身

user_list = [{'name': 'tom', 'age': 19, 'height': 1.78}, {'name': 'jerry', 'age': 25, 'height': 1.56}, {'name': 'john', 'age': 17, 'height': 1.90}]
i = 0
for user_dict in user_list:
    print(i, user_dict)
    i += 1
print("正常情況下我們要遍歷出一個巢狀字典的列表裡的所有內容")
i = 0
print("=="*20)
for i, user_dict in enumerate(user_list):
    print(i, user_dict)

上下倆段程式碼輸出的內容是一致的

0 {'name': 'tom', 'age': 19, 'height': 1.78}
1 {'name': 'jerry', 'age': 25, 'height': 1.56}
2 {'name': 'john', 'age': 17, 'height': 1.9}
正常情況下我們要遍歷出一個巢狀字典的列表裡的所有內容
========================================
0 {'name': 'tom', 'age': 19, 'height': 1.78}
1 {'name': 'jerry', 'age': 25, 'height': 1.56}
2 {'name': 'john', 'age': 17, 'height': 1.9}

2. del

​ 刪除列表裡指定的元素,使用方法有倆種。

del 列表[索引] 
del(列表[索引])
del user_list[0]
print(user_list)

1.6.8 應用:學生名片管理系統(重要)

# 學生的列表應為全域性變數,我們採用列表巢狀字典,用於儲存使用者資訊
student_list = [{'name': 'Tom', 'age': 18, 'phone': '13824719558'}]


# 主介面應為一個死迴圈,因為必須一直停留在當前頁面選擇,以下為主介面邏輯
def main():
    while True:
        menu_print()
        user_select = int(input("請輸入需要選擇的功能:"))
        if user_select == 1:
            print("新增學生資訊")
            add_student()
        elif user_select == 2:
            print("查詢所有學生資訊")
            check_all_student()
        elif user_select == 3:
            print("查詢指定學生資訊")
            check_student()
        elif user_select == 4:
            print("編輯指定學生資訊")
            edit_student()
        elif user_select == 5:
            print("刪除指定學生資訊")
            delete_student()
        elif user_select == 6:
            print("退出學生名片管理系統")
            break
        else:
            print("輸入錯誤,請重新輸入")


# 顯示主介面選單,選單是每次選擇選項並且完全選項內容後會重複出現的東西,那麼我們可以給寫成函式來重複呼叫
def menu_print():
    print("=" * 10, "學生名片管理系統", "=" * 10)
    print("1.新增學生資訊")
    print("2.查詢所有學生資訊")
    print("3.查詢指定學生資訊")
    print("4.修改指定學生資訊")
    print("5.刪除指定學生資訊")
    print("6.退出系統")
    print("=" * 40)


'''
開始做第一個選項的函式,先分清邏輯順序
首先我們要輸入3個內容,名字,年齡,電話
然後用for迴圈遍歷檢視裡面有沒有名字衝突的,如果有則新增失敗並且提醒,用break跳出迴圈
如果沒有則進入else新增使用者字典到列表裡

'''


def add_student():
    new_name = input("請輸入學生的名稱:")
    new_age = int(input("請輸入學生的年齡:"))
    new_phone = input("請輸入學生的電話號碼:")
    for a, student_dict in enumerate(student_list):
        if student_dict['name'] == new_name:
            print("該學生已經存在系統,無需再次新增")
            break
    else:
        new_student = {'name': new_name, 'age': new_age, 'phone': new_phone}
        student_list.append(new_student)
        print("新增學生資訊成功")


'''
實現查詢所有學生資訊的功能
我們直接用之前學的enumerate直接遍歷所有即可,如果為空則跳出迴圈
提示系統目前沒有任何學生資訊
'''


def check_all_student():
    if not student_list:
        print("系統目前沒有任何學生資訊,請先新增學生資訊")
    else:
        print("序號\t\t姓名\t\t年齡\t\t電話")
        for n, student_dict in enumerate(student_list):
            print('%d\t\t%s\t\t%d\t\t%s' % (n+1, student_dict['name'], student_dict['age'], student_dict['phone']))


'''
實現查詢指定學生的資訊,
首先需要input來獲取要查詢學生的名字
然後遍歷列表裡的名字,如果沒有則提示,有則顯示內容
'''


def check_student():
    check_name = input("請輸入要查詢的學生名字:")
    for c, student_dict in enumerate(student_list):
        if student_dict['name'] == check_name:
            print("查到此學生")
            print("學生資訊如下\n")
            print("序號\t\t姓名\t\t年齡\t\t電話")
            print('%d\t\t%s\t\t%d\t\t%s' % (c + 1, student_dict['name'], student_dict['age'], student_dict['phone']))

            break
        else:
            print("學生檔案裡無此學生的相關資訊,請重新確認")


'''
同樣的,我們要實現修改指定學生的檔案,也是要經過一次篩選,但是不用Break跳過迴圈,
而是重新輸入資料進行更改
'''


def edit_student():
    check_name = input("請輸入要修改的學生名字:")
    for e, student_dict in enumerate(student_list):
        if student_dict['name'] == check_name:
            print("查到此學生")
            print("學生資訊如下\n")
            print("序號\t\t姓名\t\t年齡\t\t電話")
            print('%d\t\t%s\t\t%d\t\t%s' % (e + 1, student_dict['name'], student_dict['age'], student_dict['phone']))
            edit_name = input("請輸入要更改的學生名字:")
            edit_age = int(input("請輸入要更改的學生年齡:"))
            edit_phone = input("請輸入要更改的學生電話號碼:")
            student_list[e] = {'name': edit_name, 'age': edit_age, 'phone': edit_phone}
            print("修改完成")
            break
    else:
        print("學生檔案裡無此學生的相關資訊,請重新確認")


'''
刪除指定的學生檔案同理
'''


def delete_student():
    check_name = input("請輸入要查詢的學生名字:")
    for d, student_dict in enumerate(student_list):
        if student_dict['name'] == check_name:
            print("查到此學生")
            print("學生資訊如下\n")
            print("序號\t\t姓名\t\t年齡\t\t電話")
            print('%d\t\t%s\t\t%d\t\t%s' % (d + 1, student_dict['name'], student_dict['age'], student_dict['phone']))
            del student_list[d]
            print("已刪除該學生的資訊")
            break
        else:
            print("學生檔案裡無此學生的相關資訊,請重新確認")


main()


# 字典輸出問題,無法對齊提前列印的東西,格式化輸出也不行,感覺需要一個表格才能限制,如果製表需要匯入製表模組

下面是各項功能的測試

C:\Users\songs\AppData\Local\Programs\Python\Python38\python.exe "E:/Project/pythonProject/應用 學生管理系統.py"
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:1
新增學生資訊
請輸入學生的名稱:Kitty
請輸入學生的年齡:17
請輸入學生的電話號碼:13455977884
新增學生資訊成功
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:2
查詢所有學生資訊
序號		姓名		年齡		電話
1		Tom		18		13824719558
2		Kitty		17		13455977884
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:3
查詢指定學生資訊
請輸入要查詢的學生名字:larry
學生檔案裡無此學生的相關資訊,請重新確認
學生檔案裡無此學生的相關資訊,請重新確認
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:3
查詢指定學生資訊
請輸入要查詢的學生名字:tom
學生檔案裡無此學生的相關資訊,請重新確認
學生檔案裡無此學生的相關資訊,請重新確認
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:3
查詢指定學生資訊
請輸入要查詢的學生名字:Tom
查到此學生
學生資訊如下

序號		姓名		年齡		電話
1		Tom		18		13824719558
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:4
編輯指定學生資訊
請輸入要修改的學生名字:larry
學生檔案裡無此學生的相關資訊,請重新確認
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:4
編輯指定學生資訊
請輸入要修改的學生名字:Kitty
查到此學生
學生資訊如下

序號		姓名		年齡		電話
2		Kitty		17		13455977884
請輸入要更改的學生名字:Kitty
請輸入要更改的學生年齡:19
請輸入要更改的學生電話號碼:13459844657
修改完成
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:2
查詢所有學生資訊
序號		姓名		年齡		電話
1		Tom		18		13824719558
2		Kitty		19		13459844657
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:5
刪除指定學生資訊
請輸入要查詢的學生名字:larry
學生檔案裡無此學生的相關資訊,請重新確認
學生檔案裡無此學生的相關資訊,請重新確認
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:5
刪除指定學生資訊
請輸入要查詢的學生名字:Kitty
學生檔案裡無此學生的相關資訊,請重新確認
查到此學生
學生資訊如下

序號		姓名		年齡		電話
2		Kitty		19		13459844657
已刪除該學生的資訊
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:2
查詢所有學生資訊
序號		姓名		年齡		電話
1		Tom		18		13824719558
========== 學生名片管理系統 ==========
1.新增學生資訊
2.查詢所有學生資訊
3.查詢指定學生資訊
4.修改指定學生資訊
5.刪除指定學生資訊
6.退出系統
========================================
請輸入需要選擇的功能:6
退出學生名片管理系統

Process finished with exit code 0

我們做一個功能之前一定要先理清楚,主次邏輯,主邏輯我們要實現什麼功能,實現完成再去分次選項的實現,再把此選項的再重新做進去主功能裡。