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是所有匹配到的内容组成的列表
# 这只是一个简单的网络爬虫---->我们可以进一步转化为文本


~

猜你喜欢

转载自blog.csdn.net/qq_42615032/article/details/84870822