python基础

https://morvanzhou.github.io/tutorials/python-basic/basic/13-10-regular-expression/

一.print

**

1.转义

**

print('I\'m jerry')

I’m jerry
2.连接

print('apple'+'car')

applecar
3.输出整数

print(int(1)+2)

3
4.输出小数

print(float('1.2')+2)

3.2

二.数学

1.+ - * %
2.平方** 取整//

三.自变量

apple=10
print(apple)
a=1
b=a*2
print(b)

四.while循环

当条件满足的时候一直循环下去

condition=1
while condition<10:
    print(condition)
    condition=condition+1

1
2
3
4
5
6
7
8
9

五.for循环

相当于在迭代器的作用,在一个区间1时做什么,2时做什么。。

  • 1.有空格在for循环的里面,无for循环的外面tab和shift+tab可以改变结构
list=[1,2,3,4,5,6,23,26,65]
for i in list:
    print(i)
print('out list')

1
2
3
4
5
6
23
26
65
out list

  • 2.range(1,10)python自带 输出1~9

    range(start: int,stop: int,step:int)最后一个步长

for i in range(1,10):
    print(i);
for i in range(1,10,2):
    print(i);

1
3
5
7
9

六.if语句

if判断错误不输出

x=1
y=2
z=3
a=1
if x<y:
    print('y大')
if True:
    print('对的')
if x<y<z:
    print('x<y<z对')
if x<=a:
    print('x<=a对的')
if x==a:#不能写x=a 相当于赋值
    print('x==a right')
if x!=y:
    print('x不等于y')

y大
对的
x<y<z对
x<=a对的
x==a right
x不等于y

七.if else

if 、else 后的语句是同等的 位置(tab)是一样的,if、else后都有冒号

x=1
y=2
z=3
if x>y:
    print('x大')
else:
    print('y大')

y大

八.if elif else

if elif else是一个整体,若同时多个条件返回第一个条件满足的结果,跳出循环

x=1
if x>1:
    print('x>1')
elif x<1:
    print('x<1')
else:
    print('x=1')

x=1

x=2
if x>3:
    print('x>3')
elif x<1:
    print('x<1')
elif x>1:
    print('x>1')
else:
    print('x=2')
print('finish')

x>1

九.函数

  • 1.定义函数

     def 函数名(自变量1,自变量2...):
     	函数内部语句1
     	“”2
     	。。
     函数外部语句
    
  • 2.调用函数

     函数名(自变量1,自变量2...)#或自变量1=值,自变量2=值#若传值不全报错
    
  • 3.函数默认参数

     *也可调用函数的时候修改默认参数
     没有定义默认参数的自变量要放在定义默认参数自变量的前面*
    
def car(price,color='blue',brand='xx'):
    print('price:',price,
          'color:',color,
          'brand:',brand)
car(12);

price: 12 color: blue brand: xx

可修改默认值为red

def car(price,color='blue',brand='xx',start=True):
    print('price:',price,
          'color:',color,
          'brand:',brand,
          'start:',start)
car(12,color='red');

price: 12 color: red brand: xx start: True

  • 4.全局变量局部变量

     *全局变量一般大写
     函数里的局部变量离开函数调用会报错
     可以将函数里的局部变量用global 变量名并在函数外声明变量名=None 定义为全局变量*
    
def fun():
    a=10
    print(a)
    return a+100
print(fun())

10
110

定义全局变量,在函数中将全局变量变为局部变量

QUAN=2
def fun():
    a=QUAN
    return a+100
print(QUAN)
print(fun())

2
102

可将函数里的局部变量改成全局变量

a=None
def fun():
    global a
    a=20
    return a+100
print('a past=',a)
print(fun())
print('a now=',a)

a past= None
120
a now= 20

十.模块安装

在这里插入图片描述
在这里插入图片描述在这里插入图片描述升级模块

十一.文件读写

  • 1.\n换行符**\t tab 对齐
text='u\nr\nmy'
print(text)

u
r
my

text='\tu\n\tr\n\tmy'

‘’ u
‘’ r
‘’ my

  • 2.open 读文件方式

    使用 open 能够打开一个文件, open 的第一个参数为文件名和路径 ‘my file.txt’, 第二个参数为将要以什么方式打开它, 比如 w 为可写方式.
    如果计算机没有找到 ‘my file.txt’ 这个文件, w 方式能够创建一个新的文件, 并命名为 my file.txt

  • 3.打开文件记得要关闭

  • 4.给文件增加内容

掌握 append 的用法 :open(‘my file.txt’,‘a’) 打开类型为 a ,a 即表示 append

append_text='\nThis is appended file.'  # 为这行文字提前空行 "\n"
my_file=open('my file.txt','a')   # 'a'=append 以增加内容的形式打开
my_file.write(append_text)
my_file.close()

文章增加This is appended file.

  • 5.读取文章

    (1)读取文件内容 file.read()

file=open('my file.txt','r')#read的方式读
content=file.read()
print(content)

u
r
my
This is appended file.
(2)按行读取 file.readline()

file=open('my file.txt','r')#read的方式读
content=file.readline()
secondtime=file.readline()
print(content,secondtime)

u
r
(3)读取所有行 file.readlines()
如果想要读取所有行, 并可以使用像 for 一样的迭代器迭代这些行结果, 我们可以使用 file.readlines(), 将每一行的结果存储在 list 中, 方便以后迭代.

file=open('my file.txt','r')#read的方式读
content=file.readlines()
print(content)

[’\tu\n’, ‘\tr\n’, ‘\tmy\n’, ‘This is appended file.’]

十二.class类

1.定义一个class

  • class 定义一个类, 后面的类别首字母推荐以大写的形式定义,比如Calculator.
  • class可以先定义自己的属性,比如该属性的名称可以写为 name=‘Good Calculator’.
  • class后面还可以跟def, 定义一个函数. 比如def add(self,x,y): 加法, 输出print(x+y).
    其他的函数定义方法一样,注意这里的self 是默认值.
  • 定义自变量cal等于Calculator要加括号“()”,cal=Calculator()否则运行下面函数的时候会出现错误,导致无法调用.
class Calculator:
  name='GCalcu'
  price=1
  def add(self,x,y):
      print(self.name)
      result=x + y
      print(result)
  def times(self,x,y):
       print(x*y)


cal=Calculator()
cal.add(2,4)
cal.times(3,4)

GCalcu
6
12
2.class 类 init 功能
__init__是双下划线

  • __init__可以理解成初始化class的变量,取自英文中initial 最初的意思.可以在运行时,给初始值附值,运行c=Calculator(‘bad
    calculator’,18,17,16,15),然后调出每个初始值的值。看如下代码。


class Calculator:
    name='good calculator'
    price=18
    def __init__(self,name,price,height,width,weight):   # 注意,这里的下划线是双下划线
        self.name=name
        self.price=price
        self.h=height
        self.wi=width
        self.we=weight
""""
>>> c=Calculator('bad calculator',18,17,16,15)
>>> c.name
'bad calculator'
>>> c.price
18
>>> c.h
17
>>> c.wi
16
>>> c.we
15
>>>
""""
  • 设置属性的默认值, 直接在def里输入即可
    def init(self,name,price,height=10,width=14,weight=16):查看运行结果,三个有默认值的属性,可以直接输出默认值,这些默认值可以在code中更改,比如c.wi=17再输出c.wi就会把wi属性值更改为17.同理可推其他属性的更改方法。
class Calculator:
    name='good calculator'
    price=18
    def __init__(self,name,price,hight=10,width=14,weight=16): #后面三个属性设置默认值,查看运行
        self.name=name
        self.price=price
        self.h=hight
        self.wi=width
        self.we=weight

 """"
>>> c=Calculator('bad calculator',18)
>>> c.h
10
>>> c.wi
14
>>> c.we
16
>>> c.we=17
>>> c.we
17
""""

十三.input输入

variable=input() 表示运行后,可以在屏幕中输入一个数字,该数字会赋值给自变量

a_input=input('give a number:')
print("this number is:",a_input)
''''
give a number:9
this number is: 9

input()应用在if语句中:此例需要将input() 定义成整型,因为在if语句中自变量 a_input 对应的是1 and 2 整数型。输入的内容和判断句中对应的内容格式应该一致。

也可以将if语句中的1and2 定义成字符串

a_input=int(input('give a number:'))
if a_input==1:
    print("a:",a_input)
elif a_input==2:
    print("b",a_input)
else:
    print("x",a_input)
 ''''
 give a number:3
x 3
give a number:2
b 2

十四.元祖 列表

1.Tuple用小括号、或者无括号来表述,是一连串有顺序的数字。

a_tuple = (12, 3, 5, 15 , 6)
another_tuple = 12, 3, 5, 15 , 6
  • 增:元组不支持修改,但可以通过连接组合的方式进行增加
  • 删:del元组不支持单个元素删除,但可以删除整个元组
  • 改:元组是不可变类型,不能修改元组的元素。可通过现有的字符串拼接构造一个新元组
  • 查:通过下标索引,从0开始;[a:b]切片,顾头不顾尾
#增
a=(1,2,3,4,5)
b=(6,7)
c=a+b
print(c)
....
(1, 2, 3, 4, 5, 6, 7)
#删
del a
#改
a=(1,2,3,4,5)
a=a[1:3]
print(a)
b=(10,8,6)
b=b[2],b[0]
print(b)
....
(2, 3)
(6, 10)
#查
a=(1,2,3,4,5)
print(a[1])
print(a[0:3])
print(a[:])
....
2
(1, 2, 3)
(1, 2, 3, 4, 5)

2.List list是以中括号来命名的:
3.两者对比 他们的元素可以一个一个地被迭代、输出、运用、定位取值:

for content in  a_list:
    print(content)
''''
12
3
67
7
82

依次输出a_tuple和a_list中的各个元素:

for index in range(len(a_list)):
    print("index = ", index, ", number in list = ", a_list[index])
"""
index =  0 , number in list =  12
index =  1 , number in list =  3
index =  2 , number in list =  67
index =  3 , number in list =  7
index =  4 , number in list =  82
"""

for index in range(len(a_tuple)):
    print("index = ", index, ", number in tuple = ", a_tuple[index])
"""
index =  0 , number in tuple =  12
index =  1 , number in tuple =  3
index =  2 , number in tuple =  5
index =  3 , number in tuple =  15
index =  4 , number in tuple =  6
"""

十五.列表list

1.list添加
a = [1,2,3,4,1,1,-1]

  • (1)a.append(0) 在a的最后面追加一个0

  • (2)在指定的地方添加项:a.insert(1,0) 在位置1处添加0

  • (3)extend(),迭代的去增

a = [1,2,3,4,1,1,-1]
a.append(0)  # 在a的最后面追加一个0
print(a)
# [1, 2, 3, 4, 1, 1, -1, 0]

在指定的地方添加项:

a = [1,2,3,4,1,1,-1]
a.insert(1,0) # 在位置1处添加0
print(a)
# [1, 0, 2, 3, 4, 1, 1, -1]

extend(),迭代的去增

a = [1,2,3,4,1,1,-1]
b=[66,88]
a.extend(b)
print(a)

2.list移除**

  • (1).del:根据索引值删除元素

    del不仅可以删除整个列表,还可以删除列表中的某些元素

  • del 可以删除列表中的单个元素,也可以删除中间一段连续的元素

del listname[index]
del listname[start : end]

其中,start 表示起始索引,end 表示结束索引。del 会删除从索引 start 到 end 之间的元素,不包括 end 位置的元素。
a.remove(2) # 删除列表中第一个出现的值为2的项

a=[1,2,3,4,5]
del a[0]
print(a)
del a[1:3]
print(a)
''''
[2, 3, 4, 5]
[2, 5]
  • (2)remove():根据元素值进行删除
a = [1,2,3,4,1,1,-1]
a.remove(2) # 删除列表中第一个出现的值为2的项
print(a)
# [1, 3, 4, 1, 1, -1
  • (3)clear():删除列表所有元素(清空列表)
a=[1,2,3,4,5]
a.clear()
print(a)
....
[]
  • (4).del listname删除列表
del a

3.List 索引

  • 显示特定位:
a = [1,2,3,4,1,1,-1]
print(a[0])  # 显示列表a的第0位的值
# 1

print(a[-1]) # 显示列表a的最末位的值
# -1

print(a[0:3]) # 显示列表a的从第0位 到 第2位(第3位之前) 的所有项的值
# [1, 2, 3]

print(a[5:])  # 显示列表a的第5位及以后的所有项的值
# [1, -1]

print(a[-3:]) # 显示列表a的倒数第3位及以后的所有项的值
# [1, 1, -1]
  • 打印列表中的某个值的索引(index):
a = [1,2,3,4,1,1,-1]
print(a.index(2)) # 显示列表a中第一次出现的值为2的项的索引
# 1
  • 统计列表中某值出现的次数:
a=[1,2,3,4,5,5]
print(a.count(5))
....
2

4.List 排序listname.sort()

  • a.sort() 默认从小到大排序
a = [4,1,2,3,4,1,1,-1]
a.sort() # 默认从小到大排序
print(a)
# [-1, 1, 1, 1, 2, 3, 4, 4]
  • a.sort(reverse=True) # 从大到小排序
a.sort(reverse=True) # 从大到小排序
print(a)
# [4, 4, 3, 2, 1, 1, 1, -1]

5.改

a=[1,2,3,4,5]
a[0]=0#根据索引改,直接赋值即可
print(a)
a[1:3]=1,2 #切片去改,数值代表从某位到某位覆盖的位置,并且迭代的入
print(a)

十六.多维列表

1.创建二维列表
一个一维的List是线性的List,多维List是一个平面的

a = [1,2,3,4,1,1,-1]
b=[[1,2,3],
   [4,5,6],
   [7,8,9]]

2.索引
行列都是从0开始的

a = [1,2,3,4,1,1,-1]
b=[[1,2,3],
   [4,5,6],
   [7,8,9]]
print(a[0])
print(b[2][2])
....
1
9

十七.字典

List是有顺序地输出输入的话,那么字典的存档形式则是无顺序的
1.创建字典
在字典中,有key和 value两种元素,每一个key对应一个value,key是名字, value是内容。数字和字符串都可以当做key或者value,在同一个字典中, 并不需要所有的key或value有相同的形式。这样说, List 可以说是一种key为有序数列的字典。

a_list=[1,2,3,4,5]
d1={'apple':1,'pear':2,'orange':3}
d2={1:'a',2:'b',3:'c'}

print(d1['apple'])
print(a_list[0])

del d1['pear']
print(d1)

d1['b']=20
print(d1)
....
1
1
{'apple': 1, 'orange': 3}
{'apple': 1, 'orange': 3, 'b': 20}
  • 删除指定字典内容del d1[‘pear’]
  • 增加字典内容d1[‘b’]=20
    2.字典存储类型
    字典还可以以更多样的形式出现,例如字典的元素可以是一List,或者再是一个列表,再或者是一个function。索引需要的项目时,只需要正确指定对应的key就可以了。
def fun():
    return 0
d4={'apple':[1,2,3],'pear':{6:8,'a':2},3:fun()}
print(d4)
....
{'apple': [1, 2, 3], 'pear': {6: 8, 'a': 2}, 3: 0}

3.增

dic1  = {'name':'shuai','age':19,'sex':'man'}
dic1['height']=185   #没有键值对,添加
dic1['age'] = 16    #有这个键就覆盖
dic1.setdefault('weght',150)  # 有键值对,不做任何改变,没有才添加

4.删除

dic1.pop('age')  #有返回值,按键去删除
dic1.pop('age','没有此键')  #有返回值,按键去删除,可设置返回值
dic1.popitem()#随机删除,3.6默认从最后一个删除,返回元祖形式
# dic1.clear() 清空
# del dic1 删除

5.改

dic2={'like':'pingpang'}
dic2.update(dic1)  #有就覆盖,没有就更新进去
print(dic1)
print(dic2)

6.查

dic1 = {'name':'shuai','age':19,'sex':'man'}
print(dic1.keys())#键
print(dic1.values())#值
print(dic1.items())#列表
for i in dic1.keys():#循环输出键
    print('键:',i)
for j in dic1.values():#循环输出值
    print('值:',j)
for c,v in dic1.items():#循环输出键值
    print(c,v)
print(dic1['name'])#输出指定值
....
dict_keys(['name', 'age', 'sex'])
dict_values(['shuai', 19, 'man'])
dict_items([('name', 'shuai'), ('age', 19), ('sex', 'man')])
键: name
键: age
键: sex
值: shuai
值: 19
值: man
name shuai
age 19
sex man
shuai

十八.import 模块

import 的各种方法:
方法一:import time 指 import time 模块,这个模块可以python自带,也可以是自己安装的,比如以后会用到numpy这些模块,需要自己安装。

import time
print(time.localtime())
....
time.struct_time(tm_year=2020, tm_mon=1, tm_mday=14, tm_hour=21, tm_min=49, tm_sec=12, tm_wday=1, tm_yday=14, tm_isdst=0)

方法二:import time as __,__下划线缩写部分可以自己定义,在代码中把time 定义成 t.

import time as t
print(t.localtime()) # 需要加t.前缀来引出功能

方法三:from time import time,localtime ,只import自己想要的功能.

from time import localtime,time
print(localtime())
print(time())
....
time.struct_time(tm_year=2020, tm_mon=1, tm_mday=14, tm_hour=22, tm_min=18, tm_sec=7, tm_wday=1, tm_yday=14, tm_isdst=0)
1579011487.4361105

方法四:from time import * 输入模块的所有功能

from time import *
print(localtime())
""""
time.struct_time(tm_year=2016, tm_mon=12, tm_mday=23, tm_hour=14, tm_min=41, tm_sec=38, tm_wday=4, tm_yday=358, tm_isdst=0)
""""

十九.自己的模块

自建一个模块balance,新开一个脚本调用自己的模块,import balance

balance.py
def printdata(data):
    print(data)
import balance
balance.printdata('f')
....
f

二十.continue&break

1.跳出循环
True and False ,当输入1时,a=False时,会执行接下来的语句后再跳出这个循环。

a=True
while a:
    b=input('type sth')
    if b=='1':
        a=False
    else:
        pass#pass什么都不做
print('finish')
  ....
  type sth1
finish
若输入其他,一直循环
type sth2
type sth2
type sth

2.break
break用法,在循环语句中,使用 break, 当符合跳出条件时,会直接结束循环,这是 break 和 True False 的区别。

while True:
    b=input('type sth')
    if b=='1':
       break
    else:
        pass#pass什么都不做
    print('still in while')
print('finish')

3.continue
在代码中,满足b=1的条件时,因为使用了 continue , python 不会执行 else 后面的代码,而会直接进入下一次循环,重新开始循环。

while True:
    b=input('type sth')
    if b=='1':
       continue
    else:
        pass#pass什么都不做
    print('still in while')
print('finish')
....
type sth1
type sth

二十一.try错误处理

输出错误:try:, except … as …:
处理错误:会使用到循环语句。首先报错:没有这样的文件No such file or directory. 然后决定是否输入y, 输入y以后,系统就会新建一个文件(要用写入的类型),再次运行后,文件中就会写入sss

try:#有错误用except中语句,没有错误用else语句
    file=open('eee','r+')#r+不仅只读
except Exception as e:#接收错误 存储在e中
    print('there is no file named as eee')
    response =input('do u want to create a new file')
    if response=='y':
        file=open('eee','w')
    else:
        pass#什么都不做L
else:#如果try成功了就不需要执行2~9直接执行此行
    file.write('ssss')
file.close()

二十二.zip,lambda,map

1.zip
zip函数接受任意多个(包括0个和1个)序列作为参数,合并后返回一个tuple列表

a=[1,2,3]
b=[4,5,6]
zip(a,b)
list(zip(a,b))
for i,j in zip(a,b):
    print(i,j)
 ....
 1 4
2 5
3 6
list(zip(a,b,b))
for i,j,k in zip(a,b,b):
    print(i,j,j)
  ....
  1 4 4
2 5 5
3 6 6

2.lambda
lambda定义一个简单的函数(与def一样),实现简化代码的功能,看代码会更好理解
fun = lambda x,y : x+y, 冒号前的x,y为自变量,冒号后x+y为具体运算。

fun2=lambda x,y:x+y
print(fun2(2,3))
....
5

3.map
map是把函数和参数(可输入多个)绑定在一起。map是object形式需要用list输出

def fun(x,y):
    return x+y
print(list(map(fun,[1],[2])))#参数用列表形式
....
[3]
print(list(map(fun,[1,3],[2,5])))#参数用列表形式
....
[3, 8]

二十三.copy & deepcopy 浅复制 & 深复制

Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果。
1.id
一个对象的id值在CPython解释器里就代表它在内存中的`地址

import copy
a=[1,2,3]
b=a
print(id(a))
print(id(b))#地址相同
b[0]=0#同时a也被更改
print(b)
print(a)
print(id(a)==id(b))#完完全全相同

2.浅复制
当使用浅拷贝时,python只是拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已

c=copy.copy(a)
print(id(a)==id(c))#地址不同
c[1]=2222
print(a,c)#改变c,但无法改变a

a=[1,2,[3,4]]
c=copy.copy(a)
print(id(a)==id(c))#不相同
print(id(a[2])==id(c[2]))#相同。浅复制,第一层指定在另外的内存空间,第二层一个空间
a[0]=100
print(a[0],c[0])#c【0】没有被改变
a[2][0]=5
print(a[2][0],c[2][0])#c【2】【0】被改变了

3.深复制
deepcopy对外围和内部元素都进行了拷贝对象本身,而不是对象的引用。

d=copy.deepcopy(a)
print(id(a[2])==id(d[2]))#False。深复制任何都不同,不同的空间

二十四.Threading多线程

多线程 Threading:是一种让程序拥有分身效果.能同时处理多件事情. 一般的程序只能从上到下一行行执行代码, 不过 多线程(Threading) 就能打破这种限制.让你的程序鲜活起来.

二十五.multiprocessing 多进程

我们在多线程 (Threading) 里提到过, 它是有劣势的, GIL 让它没能更有效率的处理一些分摊的任务.而现在的电脑大部分配备了多核处理器, 多进程 Multiprocessing能让电脑更有效率的分配任务给每一个处理器, 这种做法解决了多线程的弊端. 也能很好的提升效率.

二十六.tkinter 窗口

Tkinter 是使用 python 进行窗口视窗设计的模块.简单的构造, 多平台, 多系统的兼容性, 能让它成为让你快速入门定制窗口文件的好助手.它在 python 窗口视窗模块中是一款简单型的. 所以用来入门, 熟悉 窗口视窗的使用, 非常有必要.

二十七.pickle 保存数据

1.pickle保存
pickle 是一个 python 中, 压缩/保存/提取 文件的模块. 最一般的使用方式非常简单.比如下面就是压缩并保存一个字典的方式. 字典和列表都是能被保存的.

import pickle

a_dict = {'da': 111, 2: [23,1,4], '23': {1:2,'d':'sad'}}

file=open('pickle_example.pickle','wb')
pickle.dump(a_dict,file)#将前者装载到后者
file.close()

wb 是以写的形式打开 ‘pickle_example.pickle’ 这个文件, 然后 pickle.dump 你要保存的东西去这个打开的 file.最后关闭 file 你就会发现你的文件目录里多了一个 ‘pickle_example.pickle’ 文件, 这就是那个字典了.
2.pickle 提取

with open('pickle_example.pickle','rb') as file:#用with的好处不用写close文件 也可以用with写入
    a_dict1=pickle.load(file)
print(a_dict1)

提取的时候相对简单点, 同样我们以读的形式打开那个文件, 然后 load 进一个 python 的变量.

二十八.set 找不同

1.set 基本
Set 最主要的功能就是寻找一个句子或者一个 list 当中不同的元素.

char_list = ['a', 'b', 'c', 'c', 'd', 'd', 'd']

sentence = 'Welcome Back to This Tutorial'

print(set(char_list))
# {'b', 'd', 'a', 'c'}

print(set(sentence))
# {'l', 'm', 'a', 'c', 't', 'r', 's', ' ', 'o', 'W', 'T', 'B', 'i', 'e', 'u', 'h', 'k'}

print(set(char_list+ list(sentence)))
# {'l', 'm', 'a', 'c', 't', 'r', 's', ' ', 'd', 'o', 'W', 'T', 'B', 'i', 'e', 'k', 'h', 'u', 'b'}

2.添加元素
定义好一个 set 之后我们还可以对其添加需要的元素, 使用 add 就能添加某个元素. 但是不是每一个东西都能添加, 比如一个列表.

unique_char = set(char_list)
unique_char.add('x')
# unique_char.add(['y', 'z']) this is wrong
print(unique_char)

# {'x', 'b', 'd', 'c', 'a'}

3.清除元素或 set
清除一个元素可以用 remove 或者 discard, 而清除全部可以用 clear.

unique_char.remove('x')
print(unique_char)
# {'b', 'd', 'c', 'a'}

unique_char.discard('d')
print(unique_char)
# {'b', 'c', 'a'}

unique_char.clear()
print(unique_char)
# set()

4.筛选操作
我们还能进行一些筛选操作, 比如对比另一个东西, 看看原来的 set 里有没有和他不同的 (difference).或者对比另一个东西, 看看 set 里有没有相同的 (intersection).

unique_char = set(char_list)
print(unique_char.difference({'a', 'e', 'i'}))
# {'b', 'd', 'c'}

print(unique_char.intersection({'a', 'e', 'i'}))
# {'a'}

二十九.正则表达式

正则表达式 (Regular Expression) 又称 RegEx, 是用来匹配字符的一种工具. 在一大串字符中寻找你需要的内容.它常被用在很多方面, 比如网页爬虫, 文稿整理, 数据筛选等等. 最简单的一个例子, 比如我需要爬取网页中每一页的标题.而网页中的标题常常是这种形式.

<title>我是标题</ title>

而且每个网页的标题各不相同, 我就能使用正则表达式, 用一种简单的匹配方法, 一次性选取出成千上万网页的标题信息.
正则表达式绝对不是一天就能学会和记住的, 因为表达式里面的内容非常多, 强烈建议,
现在这个阶段, 你只需要了解正则里都有些什么, 不用记住, 等到你真正需要用到它的时候, 再反过头来,
好好琢磨琢磨, 那个时候才是你需要训练自己记住这些表达式的时候.
1.简单的匹配
正则表达式无非就是在做这么一回事. 在文字中找到特定的内容, 比如下面的内容.
我们在 “dog runs to cat” 这句话中寻找是否存在 “cat” 或者 “bird”.

# matching string
pattern1 = "cat"
pattern2 = "bird"
string = "dog runs to cat"
print(pattern1 in string)    # True
print(pattern2 in string)    # False

但是正则表达式绝非不止这样简单的匹配, 它还能做更加高级的内容. 要使用正则表达式,
首先需要调用一个 python 的内置模块 re. 然后我们重复上面的步骤, 不过这次使用正则.
可以看出, 如果 re.search() 找到了结果, 它会返回一个 match 的 object. 如果没有匹配到,
它会返回 None. 这个 re.search() 只是 re 中的一个功能, 之后会介绍其它的功能.

import re

# regular expression
pattern1 = "cat"
pattern2 = "bird"
string = "dog runs to cat"
print(re.search(pattern1, string))  # <_sre.SRE_Match object; span=(12, 15), match='cat'>
print(re.search(pattern2, string))  # None

2.灵活匹配
除了上面的简单匹配, 下面的内容才是正则的核心内容, 使用特殊的 pattern 来灵活匹配需要找的文字.

如果需要找到潜在的多个可能性文字, 我们可以使用 [] 将可能的字符囊括进来. 比如 [ab] 就说明我想要找的字符可以是 a 也可以是 b.
这里我们还需要注意的是, 建立一个正则的规则, 我们在 pattern 的 “” 前面需要加上一个 r 用来表示这是正则表达式, 而不是普通字符串.
通过下面这种形式, 如果字符串中出现 “run” 或者是 “ran”, 它都能找到.

# multiple patterns ("run" or "ran")
ptn = r"r[au]n"       # start with "r" means raw string
print(re.search(ptn, "dog runs to cat"))    # <_sre.SRE_Match object; span=(4, 7), match='run'>

同样, 中括号 [] 中还可以是以下这些或者是这些的组合. 比如 [A-Z] 表示的就是所有大写的英文字母.
[0-9a-z] 表示可以是数字也可以是任何小写字母.

print(re.search(r"r[A-Z]n", "dog runs to cat"))     # None
print(re.search(r"r[a-z]n", "dog runs to cat"))     # <_sre.SRE_Match object; span=(4, 7), match='run'>
print(re.search(r"r[0-9]n", "dog r2ns to cat"))     # <_sre.SRE_Match object; span=(4, 7), match='r2n'>
print(re.search(r"r[0-9a-z]n", "dog runs to cat"))  # <_sre.SRE_Match object; span=(4, 7), match='run'>

3.按类型匹配
除了自己定义规则, 还有很多匹配的规则时提前就给你定义好了的.
下面有一些特殊的匹配类型给大家先总结一下, 然后再上一些例子.

\d : 任何数字
\D : 不是数字
\s : 任何 white space, 如 [\t\n\r\f\v]
\S : 不是 white space
\w : 任何大小写字母, 数字和 “” [a-zA-Z0-9]
\W : 不是 \w
\b : 空白字符 (只在某个字的开头或结尾)
\B : 空白字符 (不在某个字的开头或结尾)
\ : 匹配
. : 匹配任何字符 (除了 \n)
^ : 匹配开头
$ : 匹配结尾
? : 前面的字符可有可无

下面就是具体的举例说明啦.

# \d : decimal digit
print(re.search(r"r\dn", "run r4n"))           # <_sre.SRE_Match object; span=(4, 7), match='r4n'>
# \D : any non-decimal digit
print(re.search(r"r\Dn", "run r4n"))           # <_sre.SRE_Match object; span=(0, 3), match='run'>
# \s : any white space [\t\n\r\f\v]
print(re.search(r"r\sn", "r\nn r4n"))          # <_sre.SRE_Match object; span=(0, 3), match='r\nn'>
# \S : opposite to \s, any non-white space
print(re.search(r"r\Sn", "r\nn r4n"))          # <_sre.SRE_Match object; span=(4, 7), match='r4n'>
# \w : [a-zA-Z0-9_]
print(re.search(r"r\wn", "r\nn r4n"))          # <_sre.SRE_Match object; span=(4, 7), match='r4n'>
# \W : opposite to \w
print(re.search(r"r\Wn", "r\nn r4n"))          # <_sre.SRE_Match object; span=(0, 3), match='r\nn'>
# \b : empty string (only at the start or end of the word)
print(re.search(r"\bruns\b", "dog runs to cat"))    # <_sre.SRE_Match object; span=(4, 8), match='runs'>
# \B : empty string (but not at the start or end of a word)
print(re.search(r"\B runs \B", "dog   runs  to cat"))  # <_sre.SRE_Match object; span=(8, 14), match=' runs '>
# \\ : match \
print(re.search(r"runs\\", "runs\ to me"))     # <_sre.SRE_Match object; span=(0, 5), match='runs\\'>
# . : match anything (except \n)
print(re.search(r"r.n", "r[ns to me"))         # <_sre.SRE_Match object; span=(0, 3), match='r[n'>
# ^ : match line beginning
print(re.search(r"^dog", "dog runs to cat"))   # <_sre.SRE_Match object; span=(0, 3), match='dog'>
# $ : match line ending
print(re.search(r"cat$", "dog runs to cat"))   # <_sre.SRE_Match object; span=(12, 15), match='cat'>
# ? : may or may not occur
print(re.search(r"Mon(day)?", "Monday"))       # <_sre.SRE_Match object; span=(0, 6), match='Monday'>
print(re.search(r"Mon(day)?", "Mon"))          # <_sre.SRE_Match object; span=(0, 3), match='Mon'>

如果一个字符串有很多行, 我们想使用 ^ 形式来匹配行开头的字符, 如果用通常的形式是不成功的.
比如下面的 “I” 出现在第二行开头, 但是使用 r"^I" 却匹配不到第二行, 这时候, 我们要使用
另外一个参数, 让 re.search() 可以对每一行单独处理. 这个参数就是 flags=re.M, 或者这样写也行 flags=re.MULTILINE.

string = """
dog runs to cat.
I run to dog.
"""
print(re.search(r"^I", string))                 # None
print(re.search(r"^I", string, flags=re.M))     # <_sre.SRE_Match object; span=(18, 19), match='I'>

4.重复匹配
如果我们想让某个规律被重复使用, 在正则里面也是可以实现的, 而且实现的方式还有很多.
具体可以分为这三种:

  • : 重复零次或多次
  • : 重复一次或多次
    {n, m} : 重复 n 至 m 次
    {n} : 重复 n 次

举例如下:

# * : occur 0 or more times
print(re.search(r"ab*", "a"))             # <_sre.SRE_Match object; span=(0, 1), match='a'>
print(re.search(r"ab*", "abbbbb"))        # <_sre.SRE_Match object; span=(0, 6), match='abbbbb'>

# + : occur 1 or more times
print(re.search(r"ab+", "a"))             # None
print(re.search(r"ab+", "abbbbb"))        # <_sre.SRE_Match object; span=(0, 6), match='abbbbb'>

# {n, m} : occur n to m times
print(re.search(r"ab{2,10}", "a"))        # None
print(re.search(r"ab{2,10}", "abbbbb"))   # <_sre.SRE_Match object; span=(0, 6), match='abbbbb'>

5.分组
我们甚至可以为找到的内容分组, 使用 () 能轻松实现这件事. 通过分组, 我们能轻松定位所找到的内容.
比如在这个 (\d+) 组里, 需要找到的是一些数字, 在 (.+) 这个组里, 我们会找到 “Date: “ 后面的所有内容.
当使用 match.group() 时, 他会返回所有组里的内容, 而如果给 .group(2) 里加一个数, 它就能定位你需要返回哪个组里的信息.

match = re.search(r"(\d+), Date: (.+)", "ID: 021523, Date: Feb/12/2017")
print(match.group())                   # 021523, Date: Feb/12/2017
print(match.group(1))                  # 021523
print(match.group(2))                  # Date: Feb/12/2017

有时候, 组会很多, 光用数字可能比较难找到自己想要的组, 这时候, 如果有一个名字当做索引, 会是一件很容易的事.
我们字需要在括号的开头写上这样的形式 ?P<名字> 就给这个组定义了一个名字. 然后就能用这个名字找到这个组的内容.

match = re.search(r"(?P<id>\d+), Date: (?P<date>.+)", "ID: 021523, Date: Feb/12/2017")
print(match.group('id'))                # 021523
print(match.group('date'))              # Date: Feb/12/2017

6.findall
前面我们说的都是只找到了最开始匹配上的一项而已, 如果需要找到全部的匹配项, 我们可以使用 findall
功能. 然后返回一个列表. 注意下面还有一个新的知识点, | 是 or 的意思, 要不是前者要不是后者

# findall
print(re.findall(r"r[ua]n", "run ran ren"))    # ['run', 'ran']

# | : or
print(re.findall(r"(run|ran)", "run ran ren")) # ['run', 'ran']

7.replace
我们还能通过正则表达式匹配上一些形式的字符串然后再替代掉这些字符串.
使用这种匹配 re.sub(), 将会比 python 自带的 string.replace() 要灵活多变.

print(re.sub(r"r[au]ns", "catches", "dog runs to cat"))     # dog catches to cat

8.split
再来我们 Python 中有个字符串的分割功能, 比如想获取一句话中所有的单词.
比如 “a is b”.split(" "), 这样它就会产生一个列表来保存所有单词.
但是在正则中, 这种普通的分割也可以做的淋漓精致.

print(re.split(r"[,;\.]", "a;b,c.d;e"))             # ['a', 'b', 'c', 'd', 'e']

9.compile
最后, 我们还能使用 compile 过后的正则, 来对这个正则重复使用. 先将正则 compile 进一个变量,
比如 compiled_re, 然后直接使用这个 compiled_re 来搜索.

compiled_re = re.compile(r"r[ua]n")
print(compiled_re.search("dog ran to cat"))  # <_sre.SRE_Match object; span=(4, 7), match='ran'>

在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值