Python全棧(第一期)Day18
今日主要內容:
遞迴實戰複習
正則表示式
爬蟲小例子
一,遞迴複習
遞迴注意事項:
1,超過最大遞迴限制的報錯
2,只要寫遞迴函式,必須要有結束條件。
3,每一個條件之下都要有返回值
4,不要只看到return就認為已經返回了。要看返回操作是在遞迴到第幾層的時候發生的,然後返回給了誰。
1,斐波那契數求解
# 方法一 import time def fib1(n): if n == 1 or n == 2: return 1 return fib1(n-1) + fib1(n-2) start = time.time() ret = fib1(35) end = time.time() print(ret) print(end - start) print('000000000000000000000000000') # 方法二 def fib2(n, l=[0]): l[0] += 1 if n == 1 or n == 2: l[0] -= 1 return 1, 1 else: a, b = fib2(n-1) l[0] -= 1 if l[0] == 0: return a+b return b, a+b print(fib2(35)) print('000000000000000000000000000') # 方法三 def fib3(n, a=1, b=1): if n == 1: return a return fib3(n-1, b, a+b) start = time.time() ret = fib3(35) end = time.time() print(ret) print(end - start)
輸出結果:
9227465
2.2498440742492676
000000000000000000000000000
9227465
000000000000000000000000000
9227465
0.0
能夠很明顯看到第一種方法和第三種方法的耗時差異!
2,階乘
# 階乘
#3! 3*2*1
# 2! 2*1
# 1! 1
def fac(n):
if n == 1:
return 1
return n * fac(n-1)
print(fac(5))
輸出結果:
120
二,正則表示式
1,手機號碼匹配
# 方法一 while True: phone_number = input('please input your phone number : ') if len(phone_number) == 11 \ and phone_number.isdigit()\ and (phone_number.startswith('13') \ or phone_number.startswith('14') \ or phone_number.startswith('17') \ or phone_number.startswith('18')): print('是合法的手機號碼') break else: print('不是合法的手機號碼') break # 方法二 import re phone_number = input('please input your phone number : ') if re.match('^(13|14|15|17)[0-9]{9}$',phone_number): print('是合法的手機號碼') else: print('不是合法的手機號碼')
輸出結果:
please input your phone number : 17824839335
是合法的手機號碼
please input your phone number : 17824839335
是合法的手機號碼
2,re模組下的常用方法
# re:一共用三個方法 # findall # search # match ret = re.findall('[a-z]+', 'eva egon yuan') #返回所有滿足匹配條件的結果,放在列表裡 print(ret) ret = re.search('[a]', 'eva egon yuan') print(ret) if ret: print(ret.group()) # 從前往後,找到一個就返回,返回的變數需要呼叫group才能拿到結果 # 如果沒有找到,那麼返回None,呼叫group會報錯,但是我們如果用一個if語句,就一直都不會報錯。 ret = re.match('[a-z]+', 'eva egon yuan') if ret: print(ret.group()) # match是從頭開始匹配,如果正則規則從頭開始可以匹配上,就返回一個變數。 # 匹配的內容需要用group才能顯示 # 如果沒匹配上,就返回None,呼叫group會報錯~
輸出結果:
[‘eva’, ‘egon’, ‘yuan’]
<_sre.SRE_Match object; span=(2, 3), match=‘a’>
a
eva
3.split
ret = re.split('[ab]', 'abcd')
# 先按'a'分割得到''和'bcd',在對''和'bcd'分別按'b'分割
print(ret) # ['', '', 'cd']~
輸出結果:
[’’, ‘’, ‘cd’]
4,sub subn
ret = re.sub('\d', 'H', 'eva3egon4yuan4',2)
#將數字替換成'H',引數1表示只替換1個
print(ret) #evaHegon4yuan4
ret = re.subn('\d', 'H', 'eva3egon4yuan4')
#將數字替換成'H',返回元組(替換的結果,替換了多少次)
print(ret)~
輸出結果:
evaHegonHyuan4
(‘evaHegonHyuanH’, 3)
5,compile
obj = re.compile('\d{3}')
#將正則表示式編譯成為一個 正則表示式物件,規則要匹配的是3個數字
ret = obj.search('abc123eeee') #正則表示式物件呼叫search,引數為待匹配的字串
print(ret.group())
ret = obj.search('abcashgjgsdghkash4536eeee3wr2') #正則表示式物件呼叫search,引數為待匹配的字串
print(ret.group()) ~
輸出結果:
123
453
6,finditer
import re
ret = re.finditer('\d', 'ds3sy4784a') #finditer返回一個存放匹配結果的迭代器
print(ret) # <callable_iterator object at 0x10195f940>
# print(next(ret).group()) #檢視第一個結果
# print(next(ret).group()) #檢視第二個結果
# print([i.group() for i in ret]) #檢視剩餘的左右結果
for i in ret:
print(i.group())~
輸出結果:
<callable_iterator object at 0x0000029D8B089710>
3
4
7
8
4
7,可以匹配分組內數值
import re
ret = re.search('^[1-9](\d{14})(\d{2}[0-9X])?$', '37142119981009002X')
print(ret.group())
print(ret.group(0)) # 可以匹配到分組內的數值
print(ret.group(1))
print(ret.group(2))~
輸出結果:
37142119981009002X
37142119981009002X
71421199810090
02X
8,分組
'''
?:
1,在量詞前面:匹配0/1次
2. 在量詞後邊:惰性匹配的標誌
3. 放在分組第一個:取消分組優先
'''
import re
ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
print(ret) # ['oldboy'] 這是因為findall會優先把匹配結果組裡內容返回,如果想要匹配結果,取消許可權即可
ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
print(ret) # ['www.oldboy.com']
~
輸出結果:
[‘oldboy’]
[‘www.oldboy.com’]
9,split
import re
ret = re.split("\d+", "eva3egon4yuan")
print(ret) #結果 : ['eva', 'egon', 'yuan']
ret = re.split("(\d+)", "eva3egon4yuan") #有分組的時候,返回切割內容
print(ret) #結果 : ['eva', '3', 'egon', '4', 'yuan']~
輸出結果:
[‘eva’, ‘egon’, ‘yuan’]
[‘eva’, ‘3’, ‘egon’, ‘4’, ‘yuan’]
三,爬蟲的例子
import re
from urllib.request import urlopen
def getPage(url):
response = urlopen(url)
return response.read().decode('utf-8')
def parsePage(s):
ret = re.findall(
'<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*?<span class="title">(?P<title>.*?)</span>'
'.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)評價</span>',s,re.S)
return ret
def main(num):
url = 'https://movie.douban.com/top250?start=%s&filter=' % num
response_html = getPage(url)
ret = parsePage(response_html)
print(ret)
count = 0
for i in range(10): # 10頁
main(count)
count += 25
# url從網頁上把程式碼搞下來
# bytes decode ——> utf-8 網頁內容就是我的待匹配字串
# ret = re.findall(正則,帶匹配的字串) #ret是所有匹配到的內容組成的列表
# 這只是一個簡單的網路爬蟲---->我們可以進一步轉化為文字
~