您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關Python中遇到的“坑”,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
1.哪個是True,哪個是False?
這里要看三組代碼:
# 第一組:
>>>a = 256 >>>b = 256 >>>a is b # 第二組: >>>a = 257 >>>b = 257 >>>a is b # 第三組: >>>a = 257,b = 257 >>>a is b
問題來了,這三組代碼的運行結果分別是什么呢?答案是True、False和True。第一組和第三組結果是True好像沒問題,那為什么第二組的結果是False呢?這里先用id()來查看一下a和b的地址是什么:
# 第一組: >>>id(a) >>>1426657040 >>>id(b) >>>1426657040 # 第二組: >>>id(a) >>>363389616 >>>id(b) >>>363392912 # 第三組: >>>id(a) >>>5722000 >>>id(b) >>>5722000
可以看到第一組和第三組的a和b的id值是相同的,但是第二組是不同的。出現這種情況是因為Python為了避免重復的創建和回收,就把那些常用的整數緩存起來,每次需要使用時直接從緩存中拿,而不是重新創建,這些整數的范圍是[-5, 256],不在這個范圍之中的數字就要重新創建了。那為什么第三組的a和b是一樣的呢?這是因為Python內部做了優化,對于在同一個代碼塊中的代碼,如果出現兩個值相同的整數,那么它們將被重用。這里可以用下面的代碼進行測試:
a = 257 b = 257 def func(): c = 257 print(a is c) # False print(a is b) # True func()
這段代碼中a和b的id值是一樣的,和c的id值不同。這是因為a和b在同一個代碼塊,而c處在func函數里,屬于局部變量,和a不在同一個代碼塊。所以在創建c的時候會重新創建,但是創建b的時候會重用a這個對象。
在Python的交互式命令行中,每單獨一行都視為一個代碼塊,因此第三組中的a和b處在同一個代碼塊中,所以后者重用了前者,因此,兩個變量的id是相同的。
2.關于正則表達式re.sub()
都知道正則表達式中的re.sub()是用于字符串替換的,比如:
import re def remove_tag(html): text = re.sub('<.*?>', '', html, re.S) return text
這段代碼的功能就是將html中的標簽都替換為空,沒什么好說的,這里可以用一段html代碼來測試一下:
html = """ <!DOCTYPE html><html> <head><meta charset="UTF-8"> <title>Document</title> </head><body></body></html> """ print(remove_tag(html)) # Document
運行結果和我們想象的一樣,但是如果html代碼再長一點呢?比如下面:
html = """ <!Dtp-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title> </head><bodOCTYPE html><html><head><meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta hty><h2>h2標題</h2><h3>h3標題</h3><h4>h4標題</h4></body></html> """ print(remove_tag(html))
運行結果如下:
Document h2標題h3標題h4標題</body></html>
為什么最后會多出來"</body></html>"呢?這兩個標簽不應該被替換掉嗎?問題在于re.sub()的第四個參數,這里先看下sub()函數的原型:
re.sub(pattern, repl, string, count=0, flags=0)
那為什么我們把re.S放在count的位置也沒有報錯呢?難道說re.S是一個數字?打印出來看一下:
import re print(re.S) # 16
原來re.S還可以當數字用!這時候數一下上面那段html代碼中的標簽個數,發現"</body></html>"是第17和第18個,而因為re.S被當做16傳給count參數了,就導致最后兩個標簽沒有被替換掉。
3.字符串的lstrip()
相信很多人都用過lstrip(),在處理字符串的時候很有用,比如:
print("aabbcc".lstrip('aa')) # bbcc
這很簡單,也沒什么問題,但是看下面這個例子:
print("ababacac".lstrip("ab")) # cac
為什么結果不是acac呢?這是因為當lstrip()中傳入一個字符串后,lstrip()會把這個字符串拆成一個個字符,然后才從左往右進行檢查,如果匹配到就刪除,直到出現第一個不同的字符,所以最后"ababa"被刪掉了,結果也就是"cac"了。要避免這種情況的話,可以用replace()方法進行替換。
4.嵌套列表
如果要你創建一個包含三個空列表的列表,你會怎么做呢?
# 選項1 li =[[] for i in range(3)] # 選項2 li = [[]*3] # 選項3 li = [[]]*3
如果你運行一下,就會知道選項1和選項3能夠得到我們想要的結果。這時候再運行一下下面這段代碼:
li = [[]]*3 li[0].append(1) print(li) # [[1], [1], [1]]
為什么我們明明只給第一個列表增加了一個1,但是其他兩個列表也增加了一個1呢?這是因為[[]]*3并不是創建了三個不同的列表,而是創建了三個指向同一個列表的對象,所以,當我們操作第一個列表時,其他兩個列表內容也會發生變化。
以上就是Python中遇到的“坑”,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。