最近参加了一个很水的AI-ML访学项目,由于极度水深知有些人是0python基础。
我不能这样子,借此机会来复习一下忘记很久的python,并学习一下ML

在对象-ML之前的部分(即文件之前的)均为初始笔记,后续为新进学习的

写在前面

python是一种面向对象的程序语言,最重要的体现在于定义变量是定义了数据的名称,可以理解为指向数据。简单的赋值只能改变指向关系,不能改变对应的值

在赋值、计算、函数中这一点都有体现

作为解释变量的语言,python不需要定义数据类型,而是在程序运行过程中由编译器进行改变

数据类型

python选用了动态语言类型,运行过程中可以改变数据类型

python是一种面向对象的程序语言,变量实际上是指向实际数据的“指针”,可以有多个变量指向一个实际数据

基本数据的基本函数

函数名 作用
ord() 返回Unicode字符对应的整数
chr() 返回整数所对应的Unicode字符
bin() 将整数转换成2进制字符串
oct() 将整数转化成8进制数字符串
hex() 将整数转换成16进制字符串
list() 根据传入的参数创建一个新的列表

基本数字

函数 功能
e 自然常数
pi 圆周率
log(x[,base]) 返回以base为底的对数,缺省为e
pow(x,y) 返回x的y次方
sqrt(x) 返回x的平方根
fabs(x) 返回x的绝对值
round(x[,n]) 返回浮点数x的四舍五入值,n代表几位小数
divmod(x,y) 返回x和y的商和余数

整型:int

与数学中整数概念一致:可以存储超大数,不会发生过大溢出

不同进制的前导符

二进制:0b、0B

八进制:0o,0O

十六进制:0x、0X

字符串

大小比较

可以直接使用<、>来进行字符串字典序之间的比较,返回值为一个bool类型

字符串切片

b = a [ i : j : s ] ,s表示步进,缺省为1
当s<0时,i缺省时,默认为-1. j缺省时,默认为-len(a)-1,所以 a [ : : -1 ] 相当于 a [-1 : -len(a)-1 : -1 ] ,也就是从最后一个元素到第一个元素复制一遍,即将字符串倒序

索引

正向排列:0~n-1,s[ i ]用于索引第i+1个字符
反向索引:-1~-n,用于索引从末尾开始的字符

复数

complex函数可用于创建一个值为real + imag * j 的复数

储存数据的容器

字符串、列表、元组、集合、字典

python包含6种内建的序列:列表、元组、字符串、Unicode字符串、buffer对象、xrange对象

通用序列操作

切片

  1. X [ i : j ]:引用序列中i到j-1的序列

  2. X [ i : j : k]:引用序列中i到j-1的序列,步长为k

i、j缺省分别表示从0、n+1号进行切片

如果要去序列的倒转,可以使用 X [ : : -1 ]

注意:python作为一种面向对象的语言,操作不直接对序列进行,只是引用了其中的子序列

如果要使用其中的子序列,需要创建一个新的序列进行存储

查找

v in X:返回bool值

复制序列

如果直接使用 b = a,效果是使a、b指向同一串序列,没有达到复制的效果,如果要使用复制,应该使用切片

1
b = a [ : ]

拼接、重复序列

使用+、*号可以进行序列的拼接,重复,直接修改了原来的序列

字符串

原始字符串:在字串前加r代表转义字符不要被转义,如:

1
r=r'hello\nworld'

字符串不可被修改

字符串的常见函数

1
2
3
4
5
6
7
S='Hello'
S.title() #首字母大写
S.lower() #全部小写
S.upper() #全部大写
S.strip(),S.rstrip(),S.lstrip() #删除左右空格,右空格,左空格
S.replace(old,new) #产生一个新串,不对原串进行修改
S.split(ch) #进行分隔

格式化输出

使用占位符

1
2
3
4
5
6
7
8
'Happy Birthday %s %d'%(age,name)
//- 表示左靠齐,+ 表示右靠齐
//%e:科学计数法表示的浮点数
//%g:综合%f和%e,系统自动决定是否使用科学计数法

a=3
b=3.14159
'%6.*f'%(a,b)

使用后续的括号解释占位符替代的内容

用 * 表示预留的小数点后位置大小和数字

format函数

可以用符号表示将哪个值填入哪个位置

1
2
3
'my name is {},age {}'.formt('Mary',18)
'my name is {1},age {0}'.formt(10,'Mary')
'my name is {1},age {0}{1}'.formt(10,'Mary')

使用占位符进行格式化

1
2
3
4
5
6
7
8
'{0:*>10}'.format(10) # 右对齐
'{0:*<10}'.format(10) # 左对齐
'{0:*^10}'.format(10) # 居中对齐
'{0:.2f}'.format(1/3)
'{0:b}'.format(10) # 二进制
'{0:o}'.format(10) # 八进制
'{0:x}'.format(10) # 十六进制
'{:,}'.format(12345678901) # 千分位格式化

输出结果:

1
2
3
4
5
6
7
8
'********10'
'10********'
'****10****'
'0.33'
'1010'
'12'
'a'
'12,345,678,901'

列表

列表中的元素可以修改,使用del函数进行元素的删除

1
2
name=[1,2,3,4]
del name[2]

使用切片可以进行赋值,进行列表中元素的替换

1
2
3
name=list('Perl')
name[2:]=list('ar') #实现了元素的替换
name[1:1]=[2,3,4] #实现了元素的插入

列表中的常见函数

1
2
3
4
5
6
7
8
9
10
11
L=[1,2,3,4]
x=5
L.append(x) #在列表尾部追加x
L.extend(ll) #将列表ll追加到l末尾
L.copy() #实现L的复制,建立一个新的列表
L.insert(index,x) #在下标为index处插入元素x
L.index(x) #查找并返回第一个x元素的位置
L.pop(index) #返回并删除下表为index处的元素,缺省默认是最后一个
L.remove(x) #删除第一个值为x的元素
L.reserve() #倒转列表
L.sort() #排序列表

+和extend的区别

+的作用是生成一个新的列表,对两个列表都没有进行修改

extend直接对原列表进行修改

元组

元组是不可修改的任何类型的数据的序列

字符串是不可修改的字符的序列

列表是可修改的任何类型的数据的序列

创建元组:使用 ( ) 或 tuple() 来创建一个元组

random库

1
2
3
4
5
6
7
8
import random
random.random() #返回一个介于[ 0.0 , 1.0 ]的随机浮点数
random.uniform(a,b) #返回一个介于[ a , b ]的浮点数
randon.randint(a,b) #返回一个介于[ a , b ]的整数
random.randrange(start,stop,step) #在指定范围内,获得一个随机数
random.choice(list) #从列表中获取一个随机元素
random.shuffle(list) #将一个列表中的元素随机打乱
random.sample(list,len) #从列表中获取长度为len,随机打乱的序列

一个使用random的示例:生成一个随机密码

1
2
3
4
5
6
7
8
9
import random
digits=[chr(i) for i in range(48,58)] #数字的ASCII范围
ascii_letters=[chr(i) for i in range(65,91)]+[chr[i] for i in range(97,12)]
num_of_num=randon.randint(1,7) #生成数字的个数
num_of_letter=8-num_of_num #生成字母的个数
numerics=[random.choice(digits) for i in range(num_of_num)] #随机生成数字,i用于计数
letters=[random.choice(ascii_letters) for i in range(num_of_letter)]
all_chars=numerics+letters
random.sshuffle(all_chars) #重新排列

集合

集合是无序的不重复元素的容器,符合数学上对集合的定义

列表使用 [ ] 定义,元组使用 ( ) 定义,集合使用 { } 定义

创建集合:使用 { }或 set() 来创建一个元组

如果要创建一个空集合,只能使用set(),因为空的一堆{ }是用来创建一对空字典

集合和列表最大的不同,就是集合不会出现重复的元素

集合常见函数

因为集合没有顺序,所以不能用append,但是可以用add()

1
2
3
4
s=set()
add() #添加一个元素
remove() #删除一个元素
x in s #返回是否在集合内的bool值

集合的包含关系

如果s1是s2的子集,那么称s2为s1的超集,可以使用issuperset( )进行判断

1
2
3
s1={1,2,3,4,5,6}
s2={1,2,3}
printf(s1.issupetset(s2))

>、<、>=、<=不能比较集合的大小,但可以反应集合之间的包含关系

  1. 如果s1是s2的真子集,那么s1<s2为True
  2. 如果s1是s2的子集,那么s1<=s2为True
  3. 如果s1是s2的真超集,那么s1>s2为True
  4. 如果s1是s2的超集,那么s1>=s2为True

集合之间的运算

并集: |

交集: &

差集: -

对称集: ^ ,除共同元素之外的所有元素

这四个操作都会产生新的集合,不会修改原先的集合

字典

可以使用名字作为索引来访问其中的数据,索引称之为“键”,一个键对应字典中的一个数据

创建字典score={'张三':78,'李四':92}前面的是键,后面的是数据

字典的基本操作

通过字典名和键可以访问字典中的元素

1
2
3
4
5
6
score={'张三':78,'李四':92}
score['李四']=90 #对字典中元素进行修改
del score['张三'] #删除字典中的元素

for name in score: #使用键对字典中的元素进行遍历
print(name+':'+score[name])

字典中的常见函数

1
2
3
4
5
6
7
score={'张三':78,'李四':92}
l=list(score.keys()) #返回由全部键组成的一个序列
ll=list(score.values()) #返回由全部值组成的一个序列
lll=list(score.items()) #返回一个序列,每一项是一个元组,每个元组由键和其对应的值组成
score.clear() #删除所有条目
score.get(key) #返回这个键对应的值
score.pop(key) #返回这个键对应的值,同时删除这个元素

使用多种容器的一个例题

成绩管理系统:有两种类型的输入,一种是“学号 姓名”,另一种是“学号 科目 成绩”,要求最后输出成绩表

1
2
3
4
#对于每个学术,要记录的有学号、姓名、每门课的成绩
studentid={} #键是学号,值是姓名
#一个学生的所有科目的成绩
studentscore={} #键是课程名称,值是学号

最终代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 建立字典存储学生的数据
studentid = {} # 键是学号,值是姓名
# 一个学生的成绩组成一个字典,键是课程名称,值是成绩
# 学生的成绩字典再组成一个字典,键是学号,值是成绩字典
studentscore = {}
course = set() # 建立所有课表的集合,确保不会重复

while True:
line = input()
if line == 'END':
break
words = line.split()
# 如果最后的是数字,表明是成绩
if words[-1].isnumeric():
score = studentscore.get(words[0])
if score == None:
# 这个学生还没有成绩,建立这个学生的成绩字典
score = {}
# 学生的成绩字典,键是课程名称,值是成绩
score[words[1]] = words[2]
studentscore[words[0]] = score
course.add(words[1])
# 存入学生的学号,姓名信息
else:
studentid[words[0]] = words[1]

coursename = list(course)

#打印表头
print(',', end='')
for name in coursename:
print(',' + name, end='')
print()

for id in studentid.keys():
print(id + ',' + studentid[id], end='')
# 获取该学生的成绩字典
score = studentscore[id]
sum = 0
cnt = 0
# 遍历该学生的成绩字典
for name in coursename:
print(',', end='')
# 获取所有的课程名
if name in score:
print(score[name], end='')
sum += int(score[name])
cnt += 1
print(',' + str(int(sum / cnt)))

函数

函数使用def关键字进行定义:def f(n):需要说明函数名,传入的变量名

另一种方式是声明一个表达式:lambda作为表达式实现简单的功能

1
2
g=lambda x,y,z:x+y+z
print(g(1,4,5))

函数参数

默认参数

如果在函数声明中定义了参数但没有传入,则使用默认参数,在函数被定义时已经计算出来:在不同位置使用该函数时默认参数指向同一个数据

不定长数目参数

当函数参数数目不定时,* 可以讲一组可变数量的参数变为参数值的容器,如果打印b,则打印一个元组

1
2
3
4
def compute(a,*b):
print(len(b)+1)
compute(3,7,9)
compute(5,8,1,6,89)

还可以对原有函数进行改造:

若想要输出一句话中的若干个单词,不包含结尾的“ . ”,则可以用:

1
print(*[len(word)for word in input()[0:-1].split()])

使用两个 * * 可以将参数收集到一个字典中,参数的名称时字典的键,对应的参数是字典的值

1
2
3
4
def compute(a,**d):
print(d)
print(len(d)+1)
compute(3,x1=9,x2=1,x3=4,x4=89)

实参与形参

当实参是不可变对象时,形参值改变不会影响实参

当实参是可变对象时,形参值改变可能会影响实参(如列表)

1
2
3
4
5
6
7
8
9
10
11
12
def change1(a,b)
a=3
b=4
a=1
b=2
change(a,b) #不可以改变,改变无效

def change1(a)
a[0]=3
a[1]=11
l=[1,2]
change(l) #可以改变,改变成功

命名空间和作用域

Python解释器启动时建立的初始环境里有一个内置命名空间,记录所有标准常量名、标准函数名等。程序运行时建立一个全局命名空间,全局变量就放在这个空间中。每一个函数定义自己的命名空间,函数内部定义的变量是局部变量。如果在一个函数中定义一个变量x,在另一个函数中也定义x变量,因为是在不同的命名空间,所以两者指代的是不同的变量。但是,也可以通过多种方式获取其他命名空间的变量。每个程序在函数外是全局命名空间,在全局命名空间中的变量是全局变量。

如果局部变量和全局变量同名,那么在函数内部使用局部变量,外部使用全局变量。

如果希望在函数中使用全局变量,则应该添加global关键字

内置函数

sorted()

对字符串、列表、元组、字典进行排序

1
2
3
4
5
6
7
8
9
sorted(list,key,reserve)

print(sorted(students,key=lambda s:s[2]))
# 按年龄从小到大排序
# [('方鹏',80,14),('陈可',85,14),('江幸',89,15)]

print(sorted(students,key=lambda s:s[1],reverse=True))
# 按成绩从大到小降序
# [('江幸',89,15),('陈可',85,14),('方鹏',80,14)]

key是排序的对象,reserve是升序(默认)还是降序(True)

对列表进行排序的sort是对已经存在的列表进行操作

sorted是返回一个新的列表

map()

map()会根据提供的函数对指定序列做映射

1
map(function,list)

调用function函数,对列表进行操作

1
printf(list(map(lambda x,y:x+y,[1,3,5,7,9],[2,4,6,8,10])))

zip()

将对象中的元素打包生成元组

1
2
3
4
5
6
7
8
9
10
a=[1,2,3]
b=[4,5,6]
l=list(zip(a,b))
#l=[(1,4),(2,5),(3,6)]

#交换字典的值和键
d={'blue': 500,'red': 100,'white':300}
d1=dict(z ip(d.values(),d.keys())
print(d1)
#{500:'blue',100:'red',300:'white'}

其他

  1. eval()函数计算表达式的值
  2. exec()函数运行python语句
  3. all()参数都为True返回True
  4. any()参数有一个True返回True**(空列表和0都表示False)**

程序结构

模块

import xx就是导入一个模块,一个python文件就是一个模块

1
2
3
4
5
import compute
#导入了compute.py这个python文件

#不引入所有的程序
from math import sqrt

sys函数

sys模块是Python的自带模块,可利用import语句导入sys模块。当执行import sys后,Python在``sys.path`变量中所列的目录里寻找相应的模块文件。sys模块负责程序与Python解释器的交互,提供了一系列的函数和变量,用于操控Python运行环境。

具体用法很多,此略

文件

类似于文件指针,打开后需要有一个名字

1
2
3
4
5
6
7
textFile=open("1.txt","r")
textFile.read(x) #从文件中读取指定的字节数,缺省或为负,则读取整个文件
textFile.readline() #读取一行
textFile.readlines() #读取所有行,返回列表

textFile.writes(s) #写入一个列表
textFile.writelines(s) #写入一个列表,自动换行