1 下载安装 Anaconda
- 去官网下载安装包,双击安装包安装,安装路径可自定义安装。
- 安装完成后设置环境变量,在环境变量中的 path 中添加 Anaconda 的安装路径及路径下的 Scripts 的路径
- 然后打开 cmd 命令窗口,输入 conda --version 校验是否安装成功
- 启动 Anaconda ,在电脑搜索的地方搜索 “Jupyter Notebook” 进行启动。
2 基础知识
2.1 print:用于字符串打印
语法:
print(value,...,sep='',end='')
# 1. value:输入一个或多个要打印的字符串
# 2. sep:代表可自定义 value 之间的符号,默认为空格
# 3. end:代表可自定义 value 结尾的符号,默认为换行符号
print('lemon','apple','banana',sep=',',end='.')
2.2 注释与换行操作
单行注释:
print('hello','world') # 向屏幕输出 hello world
多行注释:
'''
先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。
然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。
诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。
'''
"""
宫中府中,俱为一体,陟罚臧否,不宜异同。
若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。
"""
print('侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。')
print('愚以为宫中之事,事无大小,悉以咨之,然后施行,必能裨补阙漏,有所广益。')
print('将军向宠,性行淑均,晓畅军事,试用于昔日,先帝称之曰能,是以众议举宠为督。')
换行:
print('愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
亲贤臣,远小人,此先汉所以兴隆也;
亲小人,远贤臣,此后汉所以倾颓也。
先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。
侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。')
2.3 单引号、双引号及转义字符
print('臣本布衣,躬耕于南阳')
print("臣本布衣,躬耕于南阳")
print(''' I'm pythonic,I said:"Practice makes perfect" ''')
print(""" I'm pythonic,I said:"Practice makes perfect" """)
# 用反斜杠()转义特殊字符
print('n')
print('\n')
# 可以用 r 和 R 来定义原始字符串
print(r'\n') # 打印的是 \n
print(R'\n') # 打印的是 \n
2.4 运算符和数学函数
运算符:
# 乘方
4 ** 4 # 表示4的4次方,结果:256
# 取整
20 // 6 # 结果:3
# round 四舍五入
round(8.9) # 四舍五入保留到整数位
round(10.671,2) # 四舍五入保留小数点后两位
# abs绝对值取整
abs(-1)
math 数学函数:
import math
math.ceil(5.01) # 向上取整
math.floor(5.99) # 向下取整
math.trunc(10.9) # 截取整数位
math.pow(2,4) # 幂运算,表示2的4次方
2.5 字符串
特点:由单引号、双引号、三个单引号、三个双引号 组成
'A' + 'B' # 结果:AB
'A' * 3 # 结果:AAA
'python'[1] # 结果:y
'python'[-2] # 结果:o
'python'[1:4] # 结果:yth
'python'[2:] # 结果:thon
String.strip([chars]) :
- chars为空:去除头尾空白符(n、r、t、'',即换行、回车、制表符、空格)
- chars不为空:将chars拆成一个一个字符,去除头尾指定的字符
' abc123abc '.strip() # 结果:'abc123abc'
'abc123abc'.strip('ab') # 结果:'c123abc'
'abc123abc'.strip('ba') # 结果:'c123abc'
'eabc123abc'.strip('ba') # 结果:'eabc123abc'
'abc123cba'.strip('bac') # 结果:'123'
'abc12abc3cba'.strip('bac') # 结果:'12abc3'
' abc123abc '.lstrip() # 结果:'abc123abc '
' abc123abc '.rstrip() # 结果:' abc123abc'
'python'.startswith('p') # 结果:true
'python'.endswith('n') # 结果:true
'apple'.find('p') # 结果:1
'apple'.index('p') # 结果:1
'apple'.find('m') # 结果:-1
'apple'.index('m') # 结果:报错
'python'.replace('t','TT') # 结果:'pyTThon'
'python'.replace('python','hello') # 结果:'hello'
- %s: 使用 str() 函数进行字符串转换
- %d: 转为十进制整数
- %f: 转为浮点数
'hello %s' %('world') # 结果:'hello world'
'hello %s,%s' %('world') # 结果:报错
'hello %s,%s' %('world','apple') # 结果:'hello world,apple'
'I am %{name}s, I am %{age}s years old' %{'name':'cily','age':16} # 结果:'I am cily, I am 16 years old'
'I am %d years old' % (16) # 结果:'I am 16 years old'
'%f' % (3.14) # 结果:'3.140000'
'%.3f' % (3.14) # 结果:'3.140'
'hello {}'.format('world') # 结果:'hello world'
'hello {} {}'.format('world','python') # 结果:'hello world python'
'hello {1} {0}'.format('world','python') # 结果:'hello python world'
'I am {name}, I am {age} years old'.format(name = "cily",age = 16) # 结果:'I am cily, I am 16 years old'
2.6 Number(数字):整形、浮点型、复数
Python数字类型:整形(int)、浮点型(float)、复数(complex)、布尔型(bool)
进制转换:
- bin 转化为二进制 0b1010
- oct 转化为八进制 0o12
- int 转化为十进制 10
- hex 转化为十六进制 0xa
type(10) # int
type(10.) # float
print(3+1.0) # 4.0
print(type(3+1.0)) #
# Python 中相除,默认返回浮点型
print(3/1) # 3.0
print(type(3/1)) #
# 整除
print(3//1) # 3
print(type(3//1)) #
complex(3,) # (3+0j)
complex(3,4) # (3+4j)
complex(3,4).real # 实部,结果:3.0
complex(3,4).imag # 虚部,结果:4.0
complex('3',4) # 报错
complex('3+4j') # (3+4j)
complex('3 + 4j') # 报错
int(True) # 1
int(False) # 0
isinstance(1,int) # True
isinstance(0,int) # True
isinstance(True,int) # True
isinstance(False,int) # True
bool(1) # True
bool(0) # False
bool(-1) # True
bool(None) # False
bool() # False
bool('') # False
bool(' ') # True
bool([]) # False
bool({}) # False
2.7 列表、元组、字典
# 创建空列表
list[]
[]
# 创建只有一个元素的列表
[1,]
[1]
# 创建包含不同数据类型的列表
['a',1,2,3.14,[1,2,3,4]]
# 列表操作
['a',1,2,3.14,[1,2,3,4]][0] # 'a'
['a',1,3.14,[1,2,3,4]][3][2] # 3
[1,2] + [3.4] # [1,2,3.4]
[1,2] - [3.4] # 报错,列表间不支持相减操作
[1,2] * 5 # [1,2,1,2,1,2,1,2,1,2]
[1,2] / [3.4] # 报错,列表间不支持相除操作
- list.count(x) : 统计列表中 x 出现的次数,若不存在则返回 0
- list.append(x) : 向列表尾部追加成员 x
- list.extend(l): 向列表尾部追加另外一个列表 l
- list.index(x) : 返回参数 x 在列表中的序号,若不存在则报错
- list.insert(index, object) : 在列表指定位置插入数据
- list.pop() : 默认删除列表尾部成员,并返回删除的成员
- list.remove(x) : 删除列表中指定成员(有多个则只删除第一个),若指定成员不存在则报错
- list.reverse() : 将列表中的成员顺序颠倒
- list.sort() : 排序(要求成员间可排序,否则报错)
x = [1,2,3,4,2,5,3,8,2,9,0,19,2,14,12,34,25]
x.count(2) # 4
[1,2,3].append([7,8,9]) # [1,2,3,[7,8,9]]
[1,2,3].extend([7,8,9]) # [1,2,3,7,8,9]
[11,12,13,14].pop() # 14
[11,12,13,14].pop(1) # 12
元组基本形式:圆括号 ()
包围的数据集合,可以通过序号访问元素。一种特殊形式的列表。一但创建不可变。
【注意】:元组的元素不可变,但当元组元素为列表或字典数据类型时,列表或字典内的内容是可以变的。
# 创建空元组
()
tuple()
(1,) # 创建只有一个元素的元组不能省略这个逗号
type((1,)) # tuple
type((1)) # int
a = (1,2,3,[4,5,6])
a[1] = 10 # 报错
a[3][0] = 10 # a的值变为 (1,2,3,[10,5,6])
- 元组常见函数:
- len(tuple) # 返回元组数量
- max(tuple) # 返回元组最大值
- min(tuple) # 返回元组最小值
- tuple(seq) # 将序列转为元组
{} # 创建空字段
dict() # 创建空字段
fruits = {"lemon":5,"apple":10}
fruits['lemon'] # 5
fruits['pear'] # 通过不存在的键访问成员会报错
fruits['lemon'] = 20
fruits['pear'] = 15
del fruits['pear'] # 删除pear
fruits.clear() # 清空整个字典
del fruits # 删除 fruits
字典的键的数据类型可以是:字符串、数字、元组不可变数据类型,不能为列表类型。
- dict.copy() # 复制字典
- dict.get(key,default=None) # 获取key对应的值,若key不存在则返回default
- dict.items() # 获取由键和值组成的迭代器
- dict.keys() # 获取键的迭代器
- dict.values() # 获取值的迭代器
- dict.pop(key,[default]) # 删除key:value的指定成员对。若key不存在,则返回default
- dict.popitem() # 从字典末尾删除key:value,并返回key:value
- dict.update({key:value}) # 从另外一个字典更新成员(存在则覆盖,若不存在就创建。)
- dict.setdefault(key,default=None) # 若字典存在key,则返回对应的值(不会覆盖原值)。若不存在,则建立一个key:default的字典成员。
fruits1 = {'lemon':5,'apple':10}
fruits2 = fruits1.copy()
fruits1.get('pear','该键不存在')
fruits1.items() # dict_items([{'lemon':5},{'apple':10}])
fruits1.keys() # dict_keys(['lemon', 'apple'])
2.8 Set集合类型
集合(set):无序、不重复的数据集合。无法通过键访问成员。可以使用大括号{}或者set()函数创建集合。
# 注意:创建一个空集合必须用 set() 而不是 {},因为 {} 是创建一个空字典。
type(set()) # set
a = {1,2,3,4}
type(a) # set
b = {1,1,3,3,2,2,4,4} # 最终 b 的值为 {1,3,2,4}
c = ['lemon','lemon','apple','apple']
set(c) # 去重,结果:{'lemon','apple'}
d = {1,2,3,4,5,6}
len(d) # 6
1 in d # True
7 in d # False
d - a # 得出集合间的差集 {5,6}
d & a # 得出集合间的交集 {1,2,3,4}
d | a # 得出集合间的并集 {1,2,3,4,5,6}
2.9 Python 基本数据类型总结
2.10 变量
命名规则:只能包含字母、数字、下划线,不能以数字开头。最好用小写字母。
关键字:
False、class、finally、is、return、True、continue、for、lambda、try、None、def、from、nonlocal、while、and、del、global、not、with、as、elif、if、or、yield、assert、else、import、pass、break、raise、except、in
2.11 运算符
+
-
*
/
%
//
**
a = {1,2,3,4}
b = {1,2}
a - b # 得出集合间的差集 {3,4}
'python ' * 3 # 字符串 'python python python '
[1,2,3] * 3 # 列表 [1,2,3,1,2,3,1,2,3]
(1,2,3) * 3 # 元组 (1,2,3,1,2,3,1,2,3)
10 // 3 # 取整运算 3
10.0 // 3 # 取整运算 3.0
赋值运算符:=
+=
-=
*=
/=
%=
//+
**=
比较(关系)运算符:==
!=
=>
random_num:
print('大了')
elif guess_num0:
lemon = 5
print(lemon) # 5
for i in range(10):
lemon = 9
print(lemon) # 9
i = 1
while i=3,n∈N*)
# 实现:用户输入任意数字,返回第N项数字
def fib(num):
if num 5]
b # [6,7,8,9]
num = int(input('请输入数字:'))
fibs_list = [fib(i) for i in range(1,num+1)]
fibs_list #
2.19 面向对象
- 优点:将复杂的问题流程化,进而简单化
- 缺陷:扩展性差(如果更改需求,可能整个代码都需要重写,牵一发而动全身)
面向过程适用一些简单的、固定的、不需要更新迭代的问题,如果任务复杂,且需要不断更新迭代和维护的,推荐使用面向对象。
面向过程:
def test(x,y):
if x > y:
return x
elif x < y:
return y
return x + y
面向对象编程特点:
面向对象三大特点:
将对象的特征与行为保存起来
通过继承,子类可快速获取父类特征与行为
不同的子类对象,调用相同的父类方法,产生不同的执行结果
2.20 类
类:描述具有相同的特征和行为的对象的集合
- 通过变量可以刻画类的特征
- 通过方法可以描述类的行为
注意:类可以去定义,但不负责去执行相关方法
语法:
class 类名():
变量 # 刻画类的特征
# 实例方法
def 相关方法名(self,相关参数): # 描述类的行为
pass
# 类方法
@classmethod
def 方法名(cls,相关参数)
print('')
# 静态方法
@staticmethod
def 方法名(相关参数)
print('')
# 关于 self
# self 名称是约定成俗的
# self 指向的是类实例化后的对象本身
# self 只有在类的方法中才会有,函数是不必带有 self 的
# self 在定义类的方法(实例方法)时是必须有的
# self 在调用时不必传入相应的参数
# 通过 @classmethod 声明一个类方法
# 静态方法:与普通函数基本上没有什么区别
# 静态方法与类、对象没有太大关系的时候,可以使用该方法
# 通过 @staticmethod 声明一个静态方法
# 成员可见性:
# public 公开性 (外部可以访问相关变量,或 外部可以调用相关方法)
# private 私有性 (外部不可以访问相关变量,或 外部不可以调用相关方法)
class Men():
gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
# 初始化对象特征
print('这是构造函数 __init__')
self.name = name
self.age = age
self.__testAge = age # 私有变量:在变量前面添加两个下划线
self.salary = 0
def think(self):
print('thinking')
def __testThink(self): # 私有方法:在方法前面添加两个下划线
print('thinking')
def sleep(self):
print('sleeping')
def modify_salary(self,salary):
self.salary = salary
@classmethod
def modify_height(cls,height):
cls.avg_height += height # 修改类变量
print('Success.Now the avg_height is ' + str(cls.avg_height))
# classmethod 类方法
# cls 是区别于示例方法的 self
@staticmethod
def plus_num(x,y):
return x + y
men = Men('lemon',18) # 类实例化,生成一个对象
men.sleep()
men.think()
men.name # lemon
men.__dict__ # {'name':'lemon','age':18}
men.avg_height = 1.75 # 这样修改的不是 Men 类中的 avg_height,而是相当于在类中 __init__ 创建了一个 self.avg_height = 1.75
Men.modify_height(0.05)
Men.__dict__
men.plus_num(2,3) # 6
men.__testAge # 报错
men.testAge # 报错
men._Men__testAge # 私有变量可以通过这种方式获取
men.__testThink # 报错
men.testThink # 报错
men._Men__testThink # 私有方法可以通过这种方式调用
men.salary = 10 # 不建议这样直接修改实例变量的值,建议通过定义方法来修改实例变量的值
men.modify_salary(20)
构造函数:可以让模板生成不同特征的对象
继承:子类可以直接使用父类的功能,减少重复代码
super关键字:不仅可以调用父类的构造函数,也可调用父类实例方法
class Men(): # 父类 或 几类
gender = 'male'
avg_height = 1.7
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print('sleeping')
def think(self):
print('thinking')
class ChineseMen(Men): # 子类
def __init__(self,name,age,height):
# self.name = name
# self.age = age
# 上面两行可以改为下面这一行
# Men.__init__(self,name,age)
# 上面一行可以改为下面这一行
super(ChineseMen,self).__init__(name,age)
self.height = height
def sleep(self):
# Men.sleep(self)
# 上面一行可以改为下面这一行
super(ChineseMen,self).sleep()
print(self.name + 'is sleeping')
xiaoming = ChineseMen('xiaoming', 18, 180)
xiaoming.__dict__ # {'name':'xiaoming','age':18,'height':180}
2.21 正则表达式
import re
re.findall(pattern, string, flags) # 搜索整个字符串,返回所有匹配项
re.match(pattern, string, flags) # 从字符串首字符开始匹配,若首字符不匹配,则返回None,若匹配则返回第一个匹配对象
re.search(pattern, string, flags) # 搜索整个字符串,若全都不匹配,则返回None,若匹配则返回第一个匹配对象
# pattern 正则表达式匹配规则
# string 要进行匹配的字符串
# flags 可选参数,进行特定条件的匹配
re.sub(pattern, repl, string, count=0, flags=0) # 正则替换
# pattern 正则表达式
# repl 要替换的内容,也可以传入函数
# string 被替换的字符串
# count 默认为0,代表全部替换,1代表替换1次,2代表替换2次
match_str = 'lemon&apple&lemoon&banana&lemooon&pear&lemoooon'
re.findall('lemon',match_str) # ['lemon']
re.findall('lemo{1,4}n',match_str) # ['lemon','lemoon','lem0ooon','lemoooon']
match_str = 'bac | bbc | bcc | bdc | bec'
re.findall('b[ab]c',match_str) # ['bac','bbc']
re.findall('b[^ab]c',match_str) # ['bcc','bdc','bec']
re.findall('b[abcd]c',match_str) # ['bac','bbc','bcc','bdc']
re.findall('b[a-d]c',match_str) # ['bac','bbc','bcc','bdc']
re.findall('b[^a-d]c',match_str) # ['bec']
# d 匹配一个数字字符
# D 匹配一个非数字字符
match_str = '&a0b12c344d55&AC_'
re.findall('d',match_str)
re.findall('d{1,}',match_str)
re.findall('D',match_str)
# w 匹配一个包括下划线的单词字符
# W 匹配一个非包括下划线的单词字符
re.findall('w',match_str)
re.findall('W',match_str)
# s 匹配一个空白字符 如空格、制表符、换页符等
# S 匹配一个非空白字符
match_str = 'rt&a0b12c344d55&AC_ n'
re.findall('s',match_str)
re.findall('S',match_str)
# 贪婪匹配
# 贪婪 倾向于最大长度匹配
# 非贪婪 倾向于最小长度匹配
match_str = 'lemon12banana34pear56'
re.findall('[a-z]{4,6}',match_str) # ['lemon','banana','pear']
re.findall('[a-z]{4,6}?',match_str) # ['lemo','bana','pear']
# 匹配次数
# * 代表匹配前面的字符零次或多次 {0,}
# + 代表匹配前面的字符一次或多次 {1,}
# ? 代表匹配前面的字符零次或一次 {0,1}
# 对于 ? 总结:
# 1. 如果数量词后面有 ?,该 ? 代表非贪婪的关键字,倾向于取最小长度匹配
# 2. 如果字符后面有 ?,该 ? 代表匹配前面字符 0次或1次
match_str = 'abcdef 123456 abcdef 456 abc'
re.findall('[a-z]{3,6}',match_str) # ['abcdef','abcdef','abc']
# 定位符
# ^ 匹配字符串开始的位置
# $ 匹配字符串结束的位置
re.findall('^[a-z]{6}',match_str) # ['abcdef']
re.findall('[a-z]{3}$',match_str) # ['abc']
# 组的匹配
match_str = 'lemonlemonlemonappleapplepearpear'
re.findall('(lemon){3}',match_str) # ['lemon']
re.search('(lemon){3}',match_str) #
# 组 与 字符集 的区别
# (lemon) 匹配 lemon 这一组字符
# [lemon] 匹配 括号中的任意一个字母
# flags可选参数
match_str = 'lemon LEMON'
re.findall('lemon',match_str,re.I) # ['lemon','LEMON']
# . 匹配除 “n” 之外的任何单个字符
match_str = 'n123 abcr'
re.findall('.',match_str,re.S) # 使用 re.S 可以让 . 也匹配 n
match_str = 'lemonn LEMONn'
re.findall('lemon.',match_str,re.I | re.S) # ['lemonn', 'LEMONn']
# match search
match_str = 'a5678 lemon 1234'
re.findall('d',match_str) # ['5','6','7','8','1','2','3','4']
re.match('d','5678 lemon 1234') #
re.search('d',match_str) #
r = re.search('d',match_str) #
r.group() # '5'
# group 组的匹配
# match_str = 'lemonlemonlemonappleapplepearpear'
match_str = 'life is mostly happy,but sometimes sad'
# is mostly cheerful,but sometimes
# is mostly cheerful sometimes sad
r = re.search('life(.*)sad',match_str)
r #
r.group(0) # life is mostly happy,but sometimes sad
r.group(1) # is mostly happy,but sometimes
r1 = re.search('left(.*)but(.*)sad',match_str)
r1 #
r1.group(1) # is mostly happy,
r1.group(2) # sometimes
r1.group() # (' is mostly happy,',' sometimes ')
# 正则替换
match_str = 'lemon apple 123456789 lemon lemon'
re.sub('lemon','a',match_str,count=0) # 'a apple 123456789 a lemaon'
re.sub('lemon','a',match_str,count=1) # 'a apple 123456789 lemon lemon'
re.sub('lemon','a',match_str,count=2) # 'a apple 123456789 a lemon'
# 需求:数字小于 7 的,都转为 0,数字大于等于 7 的,都转为 10
def tranform(value):
pass # pass为站位操作
re.sub('d',tranform,match_str,count=0) # 'lemon apple lemon lemon'
def tranform(value):
print(value)
re.sub('d',tranform,match_str,count=0)
#
#
#
#
#
#
#
#
#
def tranform(value):
match_num = value.group()
print(match_num)
if int(match_num) < 7:
return '0'
return '10'
re.sub('d',tranform,match_str,count=0) # 'lemon apple 000000101010 lemon lemon'
正则表达式全集:
字符 | 描述 |
---|---|
将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“n”匹配一个换行符。串行“”匹配“”而“(”则匹配“(”。 | |
匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“n”或“r”之后的位置。 | |
$ | 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“n”或“r”之前的位置。 |
* | 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。 |
? | 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。 |
{n} | n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。 |
{n,} | n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。 |
{n,m} | m和n均为非负整数,其中n |
x|y | 匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。 |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。 |
b | 匹配一个单词边界,也就是指单词和空格间的位置。例如,“erb”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。 |
B | 匹配非单词边界。“erB”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。 |
cx | 匹配由x指明的控制字符。例如,cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。 |
d | 匹配一个数字字符。等价于[0-9]。 |
D | 匹配一个非数字字符。等价于[^0-9]。 |
f | 匹配一个换页符。等价于x0c和cL。 |
n | 匹配一个换行符。等价于x0a和cJ。 |
r | 匹配一个回车符。等价于x0d和cM。 |
s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ fnrtv]。 |
S | 匹配任何非空白字符。等价于[^ fnrtv]。 |
t | 匹配一个制表符。等价于x09和cI。 |
v | 匹配一个垂直制表符。等价于x0b和cK。 |
w | 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]” |
W | 匹配任何非单词字符。等价于“[^A-Za-z0-9_]” |
xn | 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“x41”匹配“A”。“x041”则等价于“x04&1”。正则表达式中可以使用ASCII编码。. |
num | 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)1”匹配两个连续的相同字符。 |
n | 标识一个八进制转义值或一个向后引用。如果n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。 |
nm | 标识一个八进制转义值或一个向后引用。如果nm之前至少有nm个获得子表达式,则nm为向后引用。如果nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则nm将匹配八进制转义值nm。 |
nml | 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。 |
un | 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,u00A9匹配版权符号(©)。 |
常用正则表达式
字符 | 描述 |
---|---|
用户名 | /^[a-z0-9_-]{3,16}$/ |
密码 | /^[a-z0-9_-]{6,18}$/ |
十六进制值 | /^#?([a-f0-9]{6}|[a-f0-9]{3})$/ |
电子邮箱 | /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})/或者/[a−zd]+([˙a−zd]+)∗@([da−z](−[da−z])?)+(1,2˙[a−z]+)+/ 或者 /^[a-zd]+(.[a-zd]+)*@([da-z](-[da-z])?)+(.{1,2}[a-z]+)+/或者/[a−zd]+([˙a−zd]+)∗@([da−z](−[da−z])?)+(1,2˙[a−z]+)+/ |
URL | /^(https?://)?([da-z.-]+).([a-z.]{2,6})([/w .-])/?$/ |
IP 地址 | /((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)/ 或者 /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ |
HTML 标签 | /^)$/ |
删除代码注释 | (? |
Unicode编码中的汉字范围 | /^[u2E80-u9FFF]+$/ |
2.22 Pycharm
官网地址:www.jetbrains.com/pycharm/
download:
- 运行 Pycharm 需要绑定 Python 解释器
- 找到 Python 的安装路径,如:D:toolspythonpython.exe
- 打开 PyCharm =》 打开项目 =》 File =》 Setting =》 Project: =》 Python Interpreter (Python解释器) =》 将Python的安装路径添加进去即可
2.23 Python 模块
基本组织结构
包(文件夹) =》 模块(文件) =》 变量、for循环、while循环、def、class
创建一个包:打开项目 =》 右键 =》 New =》 Python Package =》 例如:libs =》 会生成一个 libs文件夹,在libs文件夹下面会生成一个 init.py ,init.py 声明了 libs 是一个包,如果没有 init.py 则说明 libs 只是一个文件夹不是一个包。
在包里面可以创建很多模块,例如在 libs 下创建:p1.py、p2.py
p1.py、p2.py 两个模块在同一个包下面,根文件夹:右键 =》 Mark Directory as =》 Source Root
libs/p1.py:
a = 1
b = 2
c = 3
libs/p2.py:
import p1
# import 模块名
print(p1.a,p1.b,p1.c)
# 也可以给p1取个别名: import p1 as t
# print(t.a,t.b,t.c)
跨包访问:
main.py:
import libs.p1 as t
print(p1.a)
print(p1.b)
print(p1.c)
libs/p2.py:
from p1 import a,b,c
# from p1 import *
print(a)
print(b)
print(c)
main.py:
from libs.p1 import *
print(a)
print(b)
print(c)
设置哪些可以导入哪些不可以导入:
libs/p1.py:
__all__ = ['a','b'] # 这样在其他模块中就不能导入 c 了,只能导入 a、b
a = 1
b = 2
c = 3
- 声明一个文件夹为一个包
- import 包 实际上导入的是这个包下面的 init.py
- 该模块名为一个包名
- 自定义选择哪些模块可以导入
libs/init.py:
print('This is libs.__init__.py')
print(__name__) # libs
__all__ = ['p1'] # 自定义 libs 包下的p1模块可以呗导入,其他如p2不可被导入
main.py
import lib # 导入的是 libs 下的 __init__.py
from libs import p1
libs/init.py:
__all__ = ['p1'] # 自定义 libs 包下的p1模块可以呗导入,其他如p2不可被导入
main.py
from libs import *
print(p1.a)
print(p2.a) # 报错
libs/init.py:
print(__name__)
libs/p1.py:
def add(x,y):
sum = x + y
print(sum)
return sum
# 只有从当前模块去运行才会执行,如果在其他模块导入当前模块则不执行
if __name__ == '__main__':
add(3,4)
main.py
from libs.p1 import add
add(5,5)
2.24 迭代器、生成器、装饰器
- 迭代器:可以理解为一个容器,每次从容器中取出一个数据,直到数据被取完为止
- 自定义迭代器:
- 以类为例:需要在类中,实现两个方法 iter 与 next
其中: - iter 方法需要返回对象本身,它是for循环使用迭代器的要求;
- next 方法用于返回容器中下一个元素,当容器中的数据取完时,需要引发 StopIteration 异常。
- 以类为例:需要在类中,实现两个方法 iter 与 next
# 需求:
# 1. 自定义迭代器,通过传入最小值最大值,返回该范围所有数值的3次方
# 2. 将返回的值,存入 num_list 列表中
class Number():
def __init__(self,min,max):
self.min = min
self.max = max
def __iter__(self):
return self
def __next__(self):
# 返回这个范围内所有数值的3次方
num = self.min
if self.min =y 返回 x+y
# 如果 x =y:
return x+y
return x-y
# 匿名函数与三元表达式搭配实现
f = lambda x,y: x+y if x>=y else x-y
f(3,4) # -1
f(5,4) # 9
# 三元表达式格式
# 条件为真的结果 if 条件判断 else 条件为假的结果
# 需求:
# 输入一个单词
# 如果是小写单词,则返回小写单词,否则都返回大写单词
f = lambda x: x if x.islower() else x.upper()
f('hello')
f('Hello')
# map 格式:
map(func, *iterables)
# func 代表可接收一个函数
# iterables 代表可接收一个或多个可迭代的序列
a = [1,2,3,4,5]
# 需求:
# 生成一个列表b,列表内的元素为a列表每个元素的三次方
b = []
for i in a:
b.append(i ** 3)
b # [1,8,27,64,125]
# 用map实现
def f(x):
return x ** 3
b = map(f,a)
b #
list(b) # [1,8,27,64,125]
# 用 map 和 lambda 实现
b = map(lambda x:x**3,a)
list(b) # [1,8,27,64,125]
# 需求:将两个列表元素相加之后结果,存放在一个新列表c中
a = [1,2,3,4,5]
b = [1,2,3,4,5]
c = map(lambda x,y:x+y,a,b)
list(c) # [2,4,6,8,10]
# 长度不一样时
a = [1,2,3]
b = [1,2,3,4,5]
c = map(lambda x,y:x+y,a,b)
list(c) # [2,4,6]
# reduce 格式
from functools import reduce
reduce(function, sequence[, initial])
# function 接收一个函数
# sequence 接收一个可迭代序列
# initial 初始运算的值
a = [1,2,3,4,5]
# 需求:
# 计算a列表各元素相乘之后的值
num = reduce(lambda x,y:x*y,a) # x、y会在a中寻找,最开始x是1,y是2,相乘以后为2;然后x是2,y是3,相乘以后为6;然后x是6,y是4,相乘以后是24,以此类推
num # 120
num = reduce(lambda x,y:x*y,a,1000) # 1000*1*2
num # 120000
b = ['a','b','c']
r = reduce(lambda x,y:x+y,b)
r # 'abc'
r = reduce(lambda x,y:x+y,b,'???')
r # '???abc'
# 连续计算:计算a列表各元素相加之后的值
# filter 格式
filter(function, iterable)
# function 接收一个函数
# iterable 接收一个可迭代序列
# filter 返回结果必须是 True 或者 False
# 适用场景:用于序列元素过滤
a = [0,1,2,3,4,5]
# 需求:将 a列表中非0的元素,保存到b列表中
def f(x):
if x!=0:
return x
b = filter(f,a)
b #
list(b) # [1,2,3,4,5]
c = filter(lambda x:True if x!=0 else False,a)
list(c) # [1,2,3,4,5]
c = filter(lambda x:x,a)
list(c) # [1,2,3,4,5]
# 基本格式:
variable = [i for i in input_list if 条件判断] # for i in input_list 是for循环,for i in input_list 中的i是一个循环变量名,每次遍历可迭代序列然后添加第一个变量i,if条件判断会对第一个i进行筛选
# variable 列表名,可自定义
# i 循环变量名
# input_list 可迭代序列
# if 条件判断,如果不写的话,默认所有条件都成立
# 需求:如何快速生成一个 0-9 列表
a = [i for i in range(10)]
a # [0,1,2,3,4,5,6,7,8,9]
a = [i for i in range(10) if i>3]
a # [4,5,6,7,8,9]
# 需求:生成一个列表,列表内的元素为a列表每个元素的三次方
a = [1,2,3,4,5]
# map lambda
b = map(lambda x:x**3,a)
list(b) # [1,8,27,64,125]
c = [i**3 for i in a]
c # [1,8,27,64,125]
# 需求:将字典里面的键,保存到一个列表c中
d = {'lemon':5,'apple':3,'pear':4}
c = [i for i in d.keys()]
c # ['lemon','apple','pear']
# 扩展:将字典里的键与值,进行替换
e = {value:key for key,value in d.items()}
e # {5:'lemon',3:'apple',4:'pear'}
2.26 文件和异常
- open函数
- open(file, mode='r',buffering=-1,encoding=None, errors=None, newline=None, closefd=True, opener=None)
- 参数说明:
- file:必需,文件路径(相对或绝对路径)
- mode:可选,文件打开模式
- encoding:一般使用utf-8
- buffering:设置缓冲
- errors:报错级别
- newline:区分换行符
- closefd:传入的file参数类型
- mode 常用参数:
- r : 以只读方式打开文件
- w : 以只写方式打开文件
- 如果改文件不存在,创建新文件
- 如果改文件已存在,则覆盖原文件
- a : 打开一个文件用于追加
- 如果改文件已存在,则在最尾处追加写入
- 如果改文件不存在,创建新文件进行写入
- 更多mode参数说明,可访问:www.runoob.com/python/file…
files/文本.txt
Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。
Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。
Python 是由 Guido van Rossum 在八十年代末和九十年代初,在荷兰国家数学和计算机科学研究所设计出来的。
Python 本身也是由诸多其他语言发展而来的,这包括 ABC、Modula-3、C、C++、Algol-68、SmallTalk、Unix shell 和其他的脚本语言等等。
像 Perl 语言一样,Python 源代码同样遵循 GPL(GNU General Public License)协议。
现在 Python 是由一个核心开发团队在维护,Guido van Rossum 仍然占据着至关重要的作用,指导其进展。
Python 2.7 被确定为最后一个 Python 2.x 版本,它除了支持 Python 2.x 语法外,还支持部分 Python 3.1 语法。
main.py
# 实现简单的文件读取操作
# 文件的路径也可以用相对路径:files/文本.txt
f = open('文本.txt 的绝对路径',mode='r',encoding='utf-8')
data = f.read()
print(data)
f.close() # 用open打开要用close将文件关闭
# 为避免忘记close文件,可以用一下方式读取文件
with open('files/文本.txt',mode='r',encoding='utf-8') as f: # 用变量f来接收
data = f.read()
print(data)
- with open(file='file_path',mode='r',encoding='utf-8') as f:
- data = f.read() # 返回整个文件数据,如果文件较大,不建议用这种方法
- data1 = f.readline() # 返回一行数据
- data2 = f.readlines() # 以列表格式,返回整个文件数据
- with open(file='file_path',mode='w',encoding='utf-8') as f:
- file.write(str) # 将字符串写入文件
- file.writeline(sequence) # 向文件写入一个序列字符串列表,如果需要换行则要自己加入换行符
with open('files/文本.txt',mode='w',encoding='utf-8') as f:
#f.write('hello lemonn hello world')
f.writelines(['hello pycharmn','hello applen','hello'])
with open('files/文本.txt',mode='a',encoding='utf-8') as f:
f.write('hello lemonn hello world')
f.writelines(['hello pycharmn','hello applen','hello'])
-
(1)JSON(JavaScript Object Notation)特点:
- 1)JSON 是一种轻量级的数据交换格式,易于人阅读和编写
- 2)JSON 具有通用性,支持几乎所有的语言
- 3)JSON 支持跨平台,支持 windows,Linux,Mac平台
-
(2)常用JSON函数
- 1)json.dumps 将 Python 对象编码成 JSON 字符串
- 2)json.loads 将 已编码的 JSON 字符串解码为 Python 对象
- 3)json.dump 将 JSON 字符串数据写进文件
- 4)json.load 读取 JSON 文件里面的数据
- 5)python
- {'python':1,'Java':2,'Hadoop':3}
- {"python":1,"Java":2,"Hadoop":3}
- 6)JSON
- '{"python":1,"Java":2,"Hadoop":3}'
-
(3)Python 与 JSON 类型转换
Python JSON dict object list, tuple array str string int, float number True true False false None null 第一列文本居中 第二列文本居右
import json
def f1():
'''
对Python对象进行操作
'''
# json.dumps
# 将 Python 对象编码成 JSON 字符串
p_list = [
{'lemon':True,'apple':6},
{'pear':6,'banana':False},
]
p_dict = {'python':1,'Java':2,'Hadoop':None}
json_list = json.dumps(p_list)
json_dict = json.dumps(p_dict)
# json.loads
# 将已编码的 JSON 字符串解码为 Python 对象
list1 = json.loads(json_list)
dict1 = json.loads(json_dict)
def f2():
'''
文件的读写
'''
# 写入JSON文件
p_dict = '{"python":1,"Java":2,"hadoop":null,"lemon":true,"banana":false}'
with open('files/json_test.json','w',encoding='utf-8') as f:
json.dump(p_dict,f)
# 读取JSON文件
with open('files/json_test.json','r',encoding='utf-8') as f:
data = json.load(f)
data1 = json.loads(data)
print(data)
print(data1)
if __name__ == '__main__':
f2()
- (1)什么是异常:
- 1)异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
- 2)一般情况下,在Python无法正常处理程序时就会发生一个异常
- 3)异常是Python对象,表示一个错误
- 4)当Python脚本发生异常时我们需要捕获处理,否则程序会终止执行
- (2)捕获异常的基本格式
try: 语句一 # 检测语句一是否存在错误 except 异常名称: 语句二 # 若语句一存在错误,可以捕获错误 finally: 语句三 # 无论是否存在错误,都会执行finally内代码
- (3)常见异常名称
- BaseException: 所有异常错误
- Exception: 常规异常错误
- ZeroDivisionError: 除0异常错误
- ValueError: 值类型异常错误
- 更多异常错误,可查看:www.runoob.com/python/pyth…
exception_demo.py
def f(num):
try:
num / 0
except ZeroDivisionError as e:
print(e)
finally:
print('执行结束')
def f1(num):
try:
return int(num)
except ValueError as e:
print(e)
finally:
print('执行结束')
# 同时捕获多个异常
def f2(num):
try:
return int(num)
except ZeroDivisionError as e:
print(e)
except ValueError as e:
print(e)
finally:
print('执行结束')
# 同时捕获多个异常简写
def f3(num):
try:
return int(num)
except (ZeroDivisionError,ValueError) as e:
print(e)
finally:
print('执行结束')
def f4(num):
try:
return int(num)
except BaseException as e:
print(e)
finally:
print('执行结束')
if __name__ == '__main__':
# f(1)
f1(a)
- (1)raise 抛出异常
- 除了使用 try-except-finally 格式来捕获异常
- 也可以通过 raise 显示的引发异常
- 一旦引发 raise 后面的异常,将终止程序运行
- (2)assert 断言
- assert 的异常参数,其实就是在断言表达式后添加字符串信息,用来解释断言并更好的知道是哪里出了问题
- 基本格式:
- assert expression [,arguments]
- 如果 bool_expression 为 False,则会抛出 arguments 这个自定义异常信息
- 如果 bool_expression 为 True,则不会抛出 arguments 这个自定义异常信息
# 需求1:
# 1. 传入一个参数,判断是否为整型类型,如果不是,则抛出异常,终止程序
# 2. 判断是否大于等于5,如果小于5,则抛出异常,终止程序
def f2(num):
# if not isinstance(num,int):
# raise Exception('该参数不是一个整型类型')
# if num =5,'该参数小于5'
if __name__ == '__main__':
f2('a')
# 需求2:
# 传入若干个参数,判断参数个数如果小于等于5,则抛出异常,终止程序
def f3(*args):
# if len(args)5,'该参数个数小于等于5'
if __name__ == '__main__':
f3(1,2,3,4,5)
2.27 虚拟环境
项目A需要运行在Python2环境下,项目B需要运行在Python3环境下。
项目A和项目B,使用同一个包,但是项目A需要使用该包的1.0版本,项目B需要使用该包的2.0版本
那么创建虚拟环境,可以解决包管理的问题
pip install pipenv
创建一个文件夹
pipenv --three 会使用当前系统的Python3创建环境
pipenv shell 激活虚拟环境
pipenv --py 显示Python解释器信息
exit 退出当前的虚拟环境
(1)包下载
下载包之前,将国外下载源,更改为国内源
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
修改下载源在 Pipfile 文件中修改
pipenv install requests
pipenv install requests--2.21.0
(2)查看当前下载包情况
pip list
(3)查看当前包依赖情况
pipenv graph
(4)更新包
pipenv update requests # 更新requests
pipenv update # 更新所有包
(5)卸载包
pipenv uninstall requests # 卸载requests包
pipenv uninstall --all # 卸载全部包并从Pipfile中移除
(6)其他操作
pipenv check # 检查安全漏洞
2.28 简单爬虫实战
超文本标记语言(HyperText Markup Language),是网页制作必备的变成语言。
超文本,可以包含文字、图片、链接,甚至音乐、程序等元素
超文本标记语言的结构包括“头”部分(英语:Head)、和“主体”部分(英语:Body)
其中“头”部提供关于网页的信息,“主体”部分提供网页的具体内容
基本格式:
Document
XPath获取数据
XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。
常用路径表达式:
表达式 | 描述 |
---|---|
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
@ | 选取属性 |
files/index.html
Document
这是一级标题
这是二级标题
这是一段文字
hello lemon
hello world
这是三级标题
python
Java
Hadoop
xpath_demo.py
from lxml.html import fromstring
# fromstring 可以将字符串类型转换为html格式
with open('files/index.html','r',encoding='utf-8') as f:
data = f.read()
print(data)
print(type(data)) #
selector = fromstring(data)
print(type(selector)) #
h1 = selector.xpath('/html/body/h1/text()')[0]
h1 = selector.xpath('//h1/text()')[0]
p = selector.xpath('/html/body/p/text()')[0]
p = selector.xpath('//body/p/text()')[0]
div_ul = selector.xpath('//div/ul/text()')
div_p = selector.xpath('//div/p/text()')
div_p = selector.xpath('//div[@id="list"]/p/text()')
div_p = selector.xpath('//div[@id="list"]/p[last()]/text()')
div_p = selector.xpath('//div[@id="list"]/p[@class="Hadoop"]/text()')
- (1)明确爬取的内容
- (2)分析网页结构,找到目标的标签
- (3)分析目标标签,获取目标数据
- (4)数据入库
(1)明确爬取的内容
正在上映的电影
(2)分析网页结构,找到目标的标签
div[@id="nowplaying"]/div[@class="mod-bd"]/ul/li
(3)分析目标标签,获取目标数据
电影名称、电影评分、电影评分人数
电影时长、上映年份、地区、导演、主要演员
(4)数据入库
写入到json文件里面
Mac: fn + f6 单步调试
fn + f8 跳到下一个断点
Window: f6 单步调试
f8 跳到下一个断点
import requests # requests 这个包的将目标网站拉取下来
from lxml.html import fromstring
import json
class SpiderDouban():
def __init__(self,url):
self.url = url
self.header = {
'Accept': '',
'Accept-Encoding': '',
'Accept-Language': '',
'Host': '',
'Referer': '',
'User-Agent': '',
'': '',
}
def get_data(self):
r = requests.get(url=self.url,headers=self.headers)
data = fromstring(r.text)
selector = data.xpath('//div[@id="nowplaying"]/div[@class="mod-bd"]/ul/li')
for i in selector:
title = i.xpath('@data-title')
score = i.xpath('@data-score')
votecount = i.xpath('@data-votecount')
duration = i.xpath('@data-duration')
ralease = i.xpath('@data-ralease')
region = i.xpath('@data-region')
director = i.xpath('@data-director')
actors = i.xpath('@data-actors')
print(title)
movie_data.append({
'title': title if title else '',
'score': score if score else '',
'votecount': votecount if votecount else '',
'duration': duration if duration else '',
'ralease': ralease if ralease else '',
'region': region if region else '',
'director': director if director else '',
'actors': actors if actors else '',
})
with open('files/movie_data.json','w',encoding='utf-8') as f:
json.dump(movie_data,f,indent=1,ensure_ascii=False)
if __name__ == '__main__':
s = SpiderDouban('https://movie.douban.com/...')
s.get_data()
3 Python 可深入的方向
爬虫工程师:
相关爬虫工具:Scrapy 爬虫框架、Selerium
反爬策略(ip代理池、随机更换 User-Agent、Cookie禁用、自动限速等方法)
数据库知识(如:Mysql Oracle 等)
Web开发工程师:
相关框架:Django Flask
前端知识:JavaScript CSS HTML
数据库知识
数据分析师:
初级数据分析:
数据库相关知识:Mysql Oracle MongoDB Redis
中高级数据分析:
Python 数据科学常见包:Numpy Pandas Matplotlib Scipy
统计学知识:线性代数
机器学习常见算法:线性回归法、梯度下降法、PCA、SW、决策树、随机森林等
大数据方向:
相关工具:Spark Hadoop
其他语言基础:Java SE
Linux 相关知识
人工智能方向:
相关框架:TensorFlow (一个完全开源的人工智能框架)、Keras
相关工具:Matplotlib 、 Numpy、TensorBoard
Linux 相关知识