Python基礎 1.6 進階與強化
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
我們做一個功能之前一定要先理清楚,主次邏輯,主邏輯我們要實現什麼功能,實現完成再去分次選項的實現,再把此選項的再重新做進去主功能裡。