【Python】编程笔记3
一、dict 和 set
1、字典——dict
思想:空間換時間
dict 中的 key 必須是不可變對象
(1)定義、初始化
在其他語言中也稱為 map,使用鍵 - 值(key - value)存儲,根據key通過hash算法計算value值,可進行快速查找。
## key-value d = {'Michael':95, 'Bob':75, 'Tracy':85} print(d['Michael'])## 其他初始化方式 d['Adam'] = 67 print(d['Adam'])輸出結果:
95 67key-value 存儲方式:必須根據 key算出 value 的存放位置。
(2)查找中,如果 key 不存在, dict 就會報錯
==》檢測 key 是否在 dict 中:
- 方法一:in
- 方法二:get()方法
輸出結果
False None -1注意:
- 返回 None 的時候 Python 的交互式命令行不顯示結果。
- dict 內部存放的順序和 key 放入的順序是沒有關系的。
(3)刪除 key
pop(key) ==》key 和所對應的 value 均被刪除。
(4)dict vs. list
和 list 比較, dict 有以下幾個特點:
而 list 相反:
2、集合——set
(1)定義
set 是一組 key 的集合,不存儲 value。且 set 中的元素,沒有重復。
==》可看作數學意義上的無序和無重復元素的集合
輸出結果
{1, 2, 3, 8, 9}(2)添加元素——add(key)
s.add(4) print(s)輸出結果
{1, 2, 3, 4, 8, 9}(3)刪除元素——remove(key)
s.remove(4) print(s)輸出結果
{1, 2, 3, 8, 9}(4)其他運算
s1 = set([1, 2, 3]) s2 = set([2, 3, 4]) print(s1 & s2) ## 交集 print(s1 | s2) ## 并集輸出結果
{2, 3} {1, 2, 3, 4}二、不可變對象
問題:
a = 'abc' print(a.replace('a','A')) print(a)輸出結果
Abc abc雖然字符串有個 replace()方法,也確實變出了’Abc’,但變量 a 最后仍是’abc’,應該怎么理解呢?
分析
重點:a 是變量,而’abc’才是字符串對象
==》a 指向的對象的內容是 ’abc‘
調用 a.replace(‘a’, ‘A’) 時,作用在字符串對象 ‘abc’ 上,replace 方法創建了一個新字符串’Abc’并返回,如果我們用變量 b 指向該新字符串,就容易理解了,變量 a 仍指向原有的字符串’abc’,但變量 b 卻指向新字符串’Abc’了
==》對于不變對象來說,調用對象自身的任意方法,也不會改變該對象自身的內容。相反,這些方法會創建新的對象并返回,這樣,就保證了不可變對象本身永遠是不可變的。
三、函數
一種代碼抽象的方式。
1、調用函數
調用函數的時候,如果傳入的參數數量不對或者參數類型錯誤,會報 TypeError 的錯誤。
2、數據類型轉換函數
print(int('123')) print(int(12.34)) print(float('12.34')) print(str(1.23)) print(str(100)) print(bool(1)) print(bool(''))輸出結果
123 12 12.34 1.23 100 True False3、函數名
函數名,本質是指向一個函數對象的引用。
==》可以把函數名賦給一個變量,相當于給這個函數起了一個“別名”。
輸出結果
14、定義函數
格式:def 函數名(參數):,然后,在縮進塊中編寫函數體,函數的返回值用 return 語句返回。
如果沒有 return 語句,函數執行完畢后也會返回結果,只是結果為 None。return None 可以簡寫為 return。
(1)空函數——pass語句
pass用于占位符,可以先讓代碼運行起來,之后再進行補充。
def nop():pass還可以放在其他語句中,eg:if 語句
5、參數檢查——TypeError錯誤
- 參數個數不對
- 參數類型不對(內置函數可以檢查出來,而自己寫的會不完善==》參數類型檢查)
6、返回多個值
本質:函數可以同時返回多個值,但其實就是一個 tuple。
7、函數的參數
參數包括:必選參數、默認參數、可變參數和關鍵字參數。
==》處理復雜的參數,還可以簡化調用者的代碼
(1)位置參數(必選參數)
按照位置順序依次賦給不同的參數。
(2)默認參數
注意:
- 必選參數在前,默認參數在后。
- 多參數時,將變化大的參數放在前面,變化小的參數放在后面,變化小的參數可以作為默認參數。
- 當不按順序提供部分默認參數時,需要把參數名寫上。
==》降低調用函數的難度。
輸出結果
[1, 2, 3, 'END'] ['x', 'y', 'z', 'END'] ['END'] ['END', 'END'] ['END', 'END', 'END']原因
- 默認參數 L 是一個變量,它指向對象[],每次調用該函數,如果改變了 L 的內容,則下次調用時,默認參數的內容就變了,不再是函數定義時的[]了
==》默認參數必須指向不變對象
修改版本
def add_end(L = None):if L is None:L = []L.append('END')return Lprint(add_end([1,2,3])) print(add_end(['x','y','z'])) print(add_end()) print(add_end()) print(add_end())輸出結果
[1, 2, 3, 'END'] ['x', 'y', 'z', 'END'] ['END'] ['END'] ['END'](3)可變參數
傳入的參數個數是可變的。0 個 或 任意個
==》可變參數在函數調用時自動組裝為一個 tuple
(4)關鍵字參數
傳入 0 個或任意個含參數名的參數
==》這些關鍵字參數在函數內部自動組裝為一個 dict。
==》用于擴展函數的功能,eg:選填參數
extra 表示把 extra 這個 dict 的所有 key-value 用關鍵字參數傳入到函數的kw 參數, kw 將獲得一個 dict,注意 kw 獲得的 dict 是 extra 的一份拷貝,對 kw 的改動不會影響到函數外的 extra。
(5)命名關鍵字參數
關鍵字參數檢查
調用時,仍可傳入不受限制的關鍵字參數
def person(name, age, **kw):if 'city' in kw:passif 'job' in kw:passprint('name:',name, 'age:',age, 'others:',kw)person('Jack', 24, city='Beijing', addr='Chaoyang', zipcode=123456)輸出結果
name: Jack age: 24 others: {'city': 'Beijing', 'addr': 'Chaoyang', 'zipcode': 123456}命名關鍵字參數——只接受特定的關鍵字參數
命名關鍵字參數需要一個特殊分隔符 *,* 后面的參數被視為命名關鍵字參數。
def person(name, age, *,city, job):print(name, age, city, job)person('Jack', 24, city='Beijing', job='Enigneer')## 命名關鍵字參數可以有缺省值 def person(name, age, *,city = 'Beijing', job):print(name, age, city, job)注意:
- 命名關鍵字參數必須傳入參數名,這和位置參數不同。
- 命名關鍵字參數可以有缺省值;
(6)參數組合
參數定義順序
必選參數、默認參數、可變參數/命名關鍵字參數和關鍵字參數。其中可變參數無法與命名關鍵字參數混合。
輸出結果
a = 1 b = 2 c = 0 args = () kw = {} a = 1 b = 2 c = 3 args = () kw = {} a = 1 b = 2 c = 3 args = ('a', 'b') kw = {} a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99} a = 1 b = 2 c = 0 d = 99 kw = {'ext': None} a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'} a = 1 b = 2 c = 3 d = 99 kw = {'x': '#'}對于任意函數,都可以通過類似 func(*args, **kw)的形式調用它,無論它的參數是如何定義的。
四、遞歸函數
如果一個函數在內部調用自身本身,這個函數就是遞歸函數。
優點:簡單、邏輯清晰
1、遞歸過程
注意:防止棧溢出
在計算機中,函數調用是通過棧( stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由于棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出。
==》解決方法:尾遞歸
==》尾遞歸:在函數返回的時候,調用自身本身,并且, return 語句不能包含表達式。這樣,編譯器或者解釋器就可以把尾遞歸做優化,使遞歸本身無論調用多少次,都只占用一個棧幀,不會出現棧溢出的情況。
遺憾的是,大多數編程語言沒有針對尾遞歸做優化, Python 解釋器也沒有做優化,所以,即使把上面的 fact(n)函數改成尾遞歸方式,也會導致棧溢出。
總結
以上是生活随笔為你收集整理的【Python】编程笔记3的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 金融贷款逾期的模型构建1
- 下一篇: 【Python】编程笔记4