Python之路【第4天】

目录

  1. 正则表达式
  2. 三目运算
  3. 列表生成式
  4. 生成器:generator
  5. 斐波拉契数列生成
  6. 正则深入
  7. 冒泡排序
  8. 时间复杂度
  9. 模块介绍

正则表达式

栗子:

import re #导入类库
m1=re.match("abc","abcdef")  #如果有匹配“abc”的则返回
m2=re.match("[0-9]","6abc")  #如果第一个字符匹配数字,则返回
m3=re.match("[0-9]{1,10}","7677abc77")  #如果前面的数匹配数字,匹配次数110次,则返回
m4=re.findall("[a-zA-Z]","7677abc")  #将匹配的字母 按单个生成列表
m5=re.findall(".+","7546abc89")  #匹配任意字符,任意次数,返回列表
m6=re.search("\d+","7546abc89")  #找出匹配数字,只会匹配第一次,就返回
m7=re.sub("\d+","*","7546abc89")  #将所有数字组替换成星号

if m1:
    print ("m1:",m1)
    print("m1.group():",m1.group())
print("---------")
print("m2.group():",m2.group())
print("---------")
print("m3.group():",m3.group())
print("---------")
print ("m4:",m4)
print("---------")
print("m5:",m5)
print("---------")
print("m6.group():",m6.group())
print("---------")
print("m7:",m7)
#结果为:
m1: <_sre.SRE_Match object; span=(0, 3), match='abc'>
m1.group(): abc
---------
m2.group(): 6
---------
m3.group(): 7677
---------
m4: ['a', 'b', 'c']
---------
m5: ['7546abc89']
---------
m6.group(): 7546
---------
m7: *abc*
#ps 有的返回的是group字符串 ,有的是返回列表
  1. .* #匹配0到多个
  2. .+ #匹配1到多个
  3. \w #匹配所有字母数字
  4. \W #匹配所有非字母数字
  5. \s #匹配空白字符
  6. \S #匹配非空字符
  7. \d #匹配所有数字
  8. \D #匹配任意非数字
  9. ^ # ^\d 以数字开头 , [^\d] 非数字
  10. $ #以。。。结尾

三目运算

ret= 3 if 3 < 5 else 5  #如果条件成立 则将3赋值给ret ,否则将5赋值给ret
print(ret)
#结果为:
3

列表生成式,迭代器&生成器

列表生成式

要求将列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 每个值加一

方法一:


a=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b=[]
for i in a :
    b.append(i+1)
a=b
print("新的a:",a)
#结果为:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

方法二:

a=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for index,i in enumerate(a):
    a[i]+=1
print("新的a:",a)
#直接修改原表

方法3:

a=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a=map(lambda x:x+1 ,a)
print("新的a:",a)
print("新的a:",type(a))
for i in a :
    print (i)
#结果为:
新的a: <map object at 0x0000027D8B8FEF28>
新的a: <class 'map'>
1
2
……
#这样a被转化成了 map, 遍历才能打印出,可以强制转化为列表

方法4:

a=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a=[i+1 for i in range(10)]
print("新的a:",a)
迭代器

我们已经知道,可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

迭代器是访问集合元素的一种方式,迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问,不能后退,只能前进,迭代器在迭代到某元素时才计算该元素,而在这之前,元素可以不存在,这个特点可以遍历巨大的集合。

a=iter([1,2,3,4,5])
print(a.__next__())
print(a.__next__())
......
#结果为:
1
2
......
生成器:generator

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

g=(x*x for x in range(1,5))
for i in g:
    print (i)
#结果为:
1
4
9
16
#ps: 可以用 next(g) 一个一个的取
斐波拉契数列生成

方法一: 采用while循环

fib_list=[]  #定义一个空列表,用来接收斐波拉契数列
def fib(max):  #定义一个最大循环次数
    n,a,b=0,0,1  #将n,a,b 分别赋值
    while n<max:  #当n小于最大值时
        #print(b)
        a,b=b,a+b #将b的值赋给a, a+b的值赋给b
        fib_list.append(b)  #将b的值添加入列表
        n+=1
    print("fib_list:",fib_list)
    return "done"
fib(10)  #执行该函数
#结果为:
fib_list: [1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

方法二:

#采用递归
fib_list=[]  #定义一个空列表用来接收得到的值
def fib(a,b,max):
    c=a+b  #定义c
    max-=1  #每循环一次max减一
    #print (c)
    fib_list.append(c)
    if max!=0:  #如果max不等于0,继续递归
        fib(b,c,max)

fib(0,1,10)
print(fib_list)
#结果为:
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

如果函数中包含yield语法,则这个函数叫生成器
yield 一般与 send结合, yield负责接收数据

仔细观察,可以看出,fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。

也就是说,上面的函数和generator仅一步之遥。要把fib函数变成generator,只需要把print(b)改为yield b就可以了:

def fib(max):
    n,a,b=0,0,1
    while n< max:
        a,b=b,a+b
        yield b   #在循环过程中不断调用yield,就会不断中断
        n+=1
    return "done"

data=fib(10)
print(data.__next__())
print(data.__next__())
print(data.__next__())
print("干点别的事")
print(data.__next__())
#或者直接用for循环遍历
print("......\n----------")
for i in fib(3):
    print(i)
#结果为:
1
2
3
干点别的事
5
......
----------
1
2
3

在上面fib的例子,我们在循环过程中不断调用yield,就会不断中断。当然要给循环设置一个条件来退出循环,不然就会产生一个无限数列出来。

同样的,把函数改成generator后,我们基本上从来不会用next()来获取下一个返回值,而是直接使用for循环来迭代。

正则深入

import  re
str="123abc456"
p=re.compile("^[0-9]+")  #以数字开头
m=p.match(str)
print("m.group():",m.group())

#等价于
m2=re.match("^[0-9]+",str)
print("m2.group():",m2.group())
#结果为:
m.group(): 123
m2.group(): 123

#ps: 先定义一个匹配条件,可以实现复用
#匹配出ip地址
import re
str="192.168.1.233"
m=re.match("([0-9]+\.){1,3}\d{1,3}",str)
print(m.group())
#结果为:
192.168.1.233

re.split(“[0-9]”,str) #以数字为分割符生成列表
re.sub(“[0-9]”,”*”,str) #将所有数字替换成星号
re.search(“^a.*i$”,str) #匹配以a开头,i结尾的集合
re.search(“(1)(358)\d{9}”,str) #匹配手机号
re.match(r”[0-9.a-z]{1,26}@[0-9.a-z]{1,20}.[0-9a-z]{1,8}”,str) #以r开头为不转义, 邮箱匹配

分组匹配:

import re
addr="school,Beijin Changpin :010-886668"
m=re.search(r'(\w+),(.+):(\S+)',addr)  #分组匹配
print(m.group())
print(m.group(1))
print(m.group(2))
print(m.group(3))
#结果为:
school,Beijin Changpin :010-886668
school
Beijin Changpin 
010-886668

冒泡排序

data=[10,4,22,11,33,4,1,99]
怎么让data按从小到大排列

#怎么让data按从小到大排列
data=[10,4,22,11,1]
for j in range(1,len(data)):  #每次把最大的数放到最后,可以大量减少遍历次数
    for i in range(len(data)-j):  #因为遍历data的话,同时操作数据会引起混乱
        if data[i]>data[i+1]:
            data[i],data[i+1]=data[i+1],data[i]  #交换数据
print (data)
#结果为:
[1, 4, 10, 11, 22]

时间复杂度

时间频度

时间与执行的次数成正比。 时间频度记为T(n), T为执行次数,n为问题规模

时间复杂度

O(f(n)) 为时间复杂度, T(n) 可以能等于O(f(n)), f(n) 为辅助函数

指数时间

计算时间m(n) ,n呈线性增长, 所花的时间以指数增长
像 两次for循环 ,即为 n^2

T(n)=O(n^2)

若T(n)的上界与输入的大小无关,则称其具有常数时间O(1)
若遍历一次为O(n), n为常量, 也可以称之为具有常数时间

对数时间

T(n)=O(log n)
称其具有对数时间,常见的有二分搜索(递归算法),二叉树。

线性时间

T(n)=O(n)
运行的时间与输入成线性关系,正比

ps:O(n^m)>O(n)>O(log n) 即具有对数时间的算法效率最高

模块介绍

模块分为 :自定义模块,内置模块,开源模块

自定义一个网站模块,dj 模块:
自定义模块第一张图
自定义模块第二张图
自定义模块第三张图
自定义模块第四张图

以上为基本的建站流程

数据序列化

python 自己的序列化函数 需要存储为二进制

import pickle  #导入python的序列化类库
#创建一个文件,保存时用二进制编码
f=open("user_acc.txt","wb")  
info={
    "aa":"123",
    "bb":"456",
}
#将账户信息序列化,然后存储
f.write((pickle.dumps(info)))
f.close()
#结果为:
user_acc.txt内容: �}q (X   aaqX   123qX   bbqX   456qu.
#ps 为编译后的数据

f=open("user_acc.txt","rb")
#将数据读入内存,然后反序列化
data=pickle.loads(f.read())
print(data)
#结果为:
{'aa': '123', 'bb': '456'}

用json序列化, json支持所有的语言, 但是只能用于 列表,元祖,字典的序列化

import json  #导入json序列化类库
#创建一个文件,按平时保存即可
f=open("user_acc.txt","w")
info={
    "aa":"123",
    "bb":"456",
}
#将账户信息序列化,然后存储
f.write((json.dumps(info)))
f.close()
#结果为:
user_acc.txt内容:{"aa": "123", "bb": "456"}


f=open("user_acc.txt","r")
#将数据读入内存,然后反序列化
data=json.loads(f.read())
print(data)
#结果为:
{'aa': '123', 'bb': '456'}

所以python的序列化pickle,比json 更强大。 pickle 可以序列化一切对象

在及时数据的存档应用比较广泛。比如游戏存档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值