踩過了這些坑,你真的懂python基礎嗎?


一、浮點數的計算

  • 思考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('哪吒'))

  先看結果:

  

  第一個打印和第二個打印都使用的是默認參數列表,所以內存地址沒有發生變化,每次增加的值都是在原先的基礎上添加值,第二個打印重新傳入了一個空列表,此時創建了一個新的列表,內存地址發生了變化,因此它們不是一個列表


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM