一、浮點數的計算
- 思考1:打印結果是什么?
a = 0.1 b = 0.2 c = 0.3 print(b == a + a)
- 思考2:打印結果是什么?
a = 0.1 b = 0.2 c = 0.3 print(c == a + b)
是真的都返回True嗎?讓我們來看看結果:
實際上,第一種a+a相當於a*2,所以結果為0.2,浮點數在python存儲里面是不精確的,所以不能對浮點型數據直接進行精確計算,可以先轉換為整數計算后在轉化為浮點數即可,或者使用Decimal庫來處理。
二、列表的復制
- 思考:能夠使用賦值的方式復制一個列表嗎?
star_list = ['吳京', '徐崢', '黃渤', '楊冪'] star_list_copy = star_list
答案是不能,我們可以通過對兩個列表添加不同的值打印一下結果:
為啥會這樣呢?我們可以使用id()方法查看內存地址去判斷是否為同一個列表:
結果內存地址是一樣的,因此列表不能用賦值的方法去進行復制,我們可以使用以下幾種方法:
- 使用for循環結合append方法遍歷添加
star_list = ['吳京', '徐崢', '黃渤', '楊冪'] star_list_copy = [] for i in star_list: star_list_copy.append(i) print(star_list_copy)
- 使用extend方法一次性添加
star_list = ['吳京', '徐崢', '黃渤', '楊冪'] star_list_copy = [] star_list_copy.extend(star_list) print(star_list_copy)
- 使用切片方法添加
star_list = ['吳京', '徐崢', '黃渤', '楊冪'] star_list_copy = star_list[:] print(star_list_copy)
- 使用copy內置方法添加
star_list = ['吳京', '徐崢', '黃渤', '楊冪'] star_list_copy = star_list.copy() print(star_list_copy)
三、多繼承的深度優先和廣度優先
- 思考1:打印結果是什么?
class A: def run(self): print('a is 吳京') class B(A): pass class C(): def run(self): print('c is 徐崢') class D(B, C): pass D().run()
思考2:打印結果是什么?
class A: def run(self): print('a is 吳京') class B(A): pass class C(A): def run(self): print('c is 徐崢') class D(B, C): pass D().run()
問題1,D同時繼承了B和C,B又繼承了A,在B這條繼承上是D->B->A,在C這條繼承上是D->C,相當於一個V字形,這個就是典型的V型問題,它采用的是深度優先原則,打印結果為:a is 吳京
問題2,D同時繼承了B和C,B和C都繼承了A,在B這條繼承上是D->B->A,在C這條繼承上是D->C->A,相當於一個菱形,這個就是典型的菱形問題,它采用的是廣度優先原則,打印結果為:c is 徐崢
以上兩種情況使用的是python當中的C3算法來實現的,我們可以使用一種簡單的方法來獲取他的順序,即調用__mro__魔術方法
四、列表的清空
- 思考1:打印結果是什么?
star_list = ['吳京', '徐崢', '黃渤', '楊冪'] for i in star_list: star_list.remove(i) print(star_list)
- 思考2:打印結果是什么?
star_list = ['吳京', '徐崢', '黃渤', '楊冪'] for index, value in enumerate(star_list): star_list.pop(index) print(star_list)
列表被清空了嗎?沒有,讓我們先看看結果:
原因是列表本質上是可被修改的,通過for循環,每次刪除一個值后,列表就會發生改變,所以不要使用for循環去清空列表的值,建議使用clear方法:
五、列表的 +=
- 思考1:打印結果是什么?
a = [1] a_id = id(a) a += [2] a_id_new = id(a) print(a_id == a_id_new)
- 思考2:打印結果是什么?
a = [1] a_id = id(a) a = a + [2] a_id_new = id(a) print(a_id == a_id_new)
我們先來看結果:
場景1:
場景2:
結果卻不一樣,實際上在列表里面,+=相當於調用了列表的extend方法,仍然還是原來的列表,內存地址沒有發生變化,第二種實際上是賦值操作,創建了一個新的列表,所以內存地址發生了改變
六、== 和 is
- 思考:打印結果是什么?
a = [1] b = [1] print(a == b) print(a is b)
都打印為True嗎?不是,先看看實際結果:
判斷列表的時候:
-
- == 比較的是 value(值)是否相等
- is 比較的是 id 是否相同,也即兩對象是否指向的同一塊內存空間
但是對於數字型或者字符串類型,它們卻是一樣的。
七、列表的扁平化、列表降維
- 思考:如何將如下的一個列表降維?
star_list = [['吳京', '徐崢'], ['黃渤', '楊冪'], ['甄子丹', '章子怡']]
提供了如下幾種方法進行降維操作:
- for循環
- 列表推導式
- sum方法
八、列表的可變性
- 思考:打印結果是什么?
def add_movie(movie, movies=[]): movies.append(movie) return movies print(add_movie('戰狼2')) print(add_movie('流浪地球', [])) print(add_movie('哪吒'))
先看結果:
第一個打印和第二個打印都使用的是默認參數列表,所以內存地址沒有發生變化,每次增加的值都是在原先的基礎上添加值,第二個打印重新傳入了一個空列表,此時創建了一個新的列表,內存地址發生了變化,因此它們不是一個列表