今日主要内容:
递归实战复习
正则表达式
爬虫小例子
一,递归复习
递归注意事项:
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是所有匹配到的内容组成的列表
# 这只是一个简单的网络爬虫---->我们可以进一步转化为文本
~