日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Python 常见的坑汇总

發(fā)布時間:2023/11/27 生活经验 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 常见的坑汇总 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. 列表與 * 操作

Python 中,* 操作符與 list 結(jié)合使用,實現(xiàn)元素復制。

復制 5 個空列表:

In [1]: [[]] * 5
Out[1]: [[], [], [], [], []]In [2]: a = [[]] * 5In [3]: a
Out[3]: [[], [], [], [], []]In [4]: 

填充兩個元素:

In [4]: a[0].extend([1,2,3])In [5]: a[1].extend([4,5,6])

期望應該為:

[[1,3,5],[2,4,6],[],[]]

實際為:

In [6]: a
Out[6]: 
[[1, 2, 3, 4, 5, 6],[1, 2, 3, 4, 5, 6],[1, 2, 3, 4, 5, 6],[1, 2, 3, 4, 5, 6],[1, 2, 3, 4, 5, 6]]

原來 * 操作復制出的 a[0]a[1]...a[5],在內(nèi)存中標識符是相等的,實現(xiàn)的僅僅是淺復制。

In [7]: id(a[0])
Out[7]: 1641831703560In [8]: id(a[1])
Out[8]: 1641831703560In [9]: id(a[2])
Out[9]: 1641831703560In [10]: id(a[3])
Out[10]: 1641831703560

在這種場景下,希望實現(xiàn) id[0]id[1] 不相等,修改 a[1] 不會影響 a[0]
不使用 *,使用列表生成式,復制出 5 個不同 id 的內(nèi)嵌列表,這樣就能避免賦值互不干擾的問題。

In [12]: b = [[] for _ in range(5)]In [13]: b
Out[13]: [[], [], [], [], []]In [14]: id(b[0])
Out[14]: 1641875609928In [15]: id(b[1])
Out[15]: 1641875595080In [16]: id(b[2])
Out[16]: 1641875822344In [17]: b[0].extend([1,2,3])In [18]: b[1].extend([4,5,6])In [19]: b
Out[19]: [[1, 2, 3], [4, 5, 6], [], [], []]In [20]: 

2. 刪除列表元素

假設列表有重復元素,要刪除列表中指定的元素,看下面代碼:

In [20]: def del_list(a, x):...:     for i in a:...:         if i == x:...:             a.remove(i)...:     return a...:     In [21]: a = [1,2,3,2,4]In [22]: del_list(a, 2)
Out[22]: [1, 3, 4]In [23]: del_list([1,2,3,4,3,4,3], 2)
Out[23]: [1, 3, 4, 3, 4, 3]In [24]: del_list([1,2,3,4,3,4,3], 3)
Out[24]: [1, 2, 4, 4]In [25]: del_list([1,3,5,3,2], 3)
Out[25]: [1, 5, 2]

可以看到上面的刪除都是正確的,再來看下面的代碼

In [26]: del_list([1,3,3,3,3,5], 3)
Out[26]: [1, 3, 3, 5]

可以看出,刪除結(jié)果仍然是包含 3 , 為什么呢?

遍歷列表 aremove 一次,移掉位置 i 后的所有元素索引都要減一。所以,一旦刪除的元素,重復出現(xiàn)在列表中,就總會漏掉一個該刪除的元素。

正確做法,找到被刪除元素后,刪除,同時下次遍歷索引不加一;若未找到,遍歷索引加一。

一般來講,盡量避免在列表迭代的過程中對列表進行刪除、更新操作。

3. 函數(shù)默認參數(shù)為空

Python 函數(shù)的參數(shù)可設為默認值。如果一個默認參數(shù)類型為 list ,默認值為設置為 []
有下面函數(shù):

In [27]: def add_list(value, volume=[]):...:     if volume is None:...:         volume = []...:     length = len(volume)...:     for i in range(length):...:         volumn[i] = i + value...:     return volume...: 


調(diào)用 add_list 函數(shù), val 值為 10, volume 默認值,函數(shù)返回 ret 為空列表。

In [28]: ret = add_list(10)In [29]: ret
Out[29]: []In [30]: 

然后,我們向空列表 ret 中,分別添加值 1、2,打印 ret ,結(jié)果符合預期

In [30]: ret.append(1)In [31]: ret.append(2)In [32]: ret
Out[32]: [1, 2]

同樣方法,再次調(diào)用 add_list 函數(shù),第二個參數(shù)還是取默認值。預期返回值 ret 還是空列表,但是結(jié)果卻出人意料!

In [41]: ret = add_list(10)In [42]: ret
Out[42]: [10, 11]

為什么返回值為 [10,11] 呢? 按照出現(xiàn)的結(jié)果,我們猜測 [1, 2] + 10 后,不正是 [11,12]。

原來調(diào)用函數(shù) add_list 時,默認參數(shù) volume 取值為默認值時,并且 volume 作為函數(shù)的返回值。再在函數(shù)外面做一些操作,再次按照默認值調(diào)用,并返回。整個過程,默認參數(shù) volumeid 始終未變。

通過增加打印我們可以看到,確實是默認參數(shù) volumeid 始終未變。

In [45]: ret = add_list(10)
volume id is 1641863237000In [46]: ret.append(1)In [47]: ret.append(2)In [48]: ret 
Out[48]: [1, 2]In [49]: ret = add_list(10)
volume id is 1641863237000In [50]: ret
Out[50]: [10, 11]

為了避免這個隱藏的坑,函數(shù)的默認參數(shù)值切記不能設置為 [],而是為 None。這樣即便按照默認值調(diào)用多次,也會規(guī)避此風險。

In [53]: def add_list(value, volume=None):...:     print("volume id is {}".format(id(volume)))...:     if volume is None:...:         volume = []...:     length = len(volume)...:     for i in range(length):...:        volume[i] = i + value...:     return volume...:     In [58]: ret = add_list(10)
volume id is 1929553104In [59]: ret
Out[59]: []In [60]: ret.append(1)In [61]: ret.append(2)In [62]: ret
Out[62]: [1, 2]In [63]: ret = add_list(10)
volume id is 1929553104In [64]: ret
Out[64]: []

4. {} 和 ()

單個元素要被識別為元組,必須在括號后面加個逗號 , 詳見如下代碼:

In [65]: a = (10)In [66]: type(a)
Out[66]: intIn [67]: b = (10,)In [68]: type(b)
Out[68]: tuple

創(chuàng)建集合與字典,它們都用一對 {},但是默認返回字典,而不是集合。要想創(chuàng)建空集合,可使用內(nèi)置函數(shù) set()

In [69]: d = {}In [70]: type(d)
Out[70]: dictIn [71]: s = set()In [72]: type(s)
Out[72]: set

5. 多值賦值順序


多值賦值是先計算出等號右側(cè)的所有變量值后,再賦值給等號左側(cè)變量。

In [73]: a, b = 1, 2In [74]: a, b = b+1, a+b In [75]: a, b
Out[75]: (3, 3)

總結(jié)

以上是生活随笔為你收集整理的Python 常见的坑汇总的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。