Python学习笔记

说在前面

不知不觉自己已经高中毕业了(并不),这个暑假需要学点什么,然后就买了一本《Python编程从入门到实践》,并夕夕上只要25块,看起来超值。然后暑假就学习如何用Python来编写程序吧,至于C++的康复计划,留到以后有时间再说。所以下面就记录一些经常需要查询的东西,帮助自己学习Python。

Python

字符串修改

title() 使字符串中单词的一个字母大写

upper() 使字符串中所有字母大写

lower() 使字符串中所有字母小写


两个字符串可以直接相加:

1
2
3
4
First_Name="Katou"
Last_Name="Megumi"
Name=First_Name+" "+Last_Name
print(Name)

输出结果就是 Katou Megumi


strip 「脱光衣服」

rstrip() 删除字符串里所有的空格

lstrip() 删除字符串开头的空格

strip() 删除字符串开头和末尾的空格

数字

在Python3中,两个整数相除的结果并非整数,而是浮点数,如果需要得到整除数,则需要将结果强制转换为整数即刻。

1
2
3
a,b=input().split()
ans=int(a/b)
print(ans)

这样输出的就是整数了。


注释

#后面接单行注释

1
2
3
4
5
6
7
'''
下面
就可以
多行
注释
'''

The Zen of Python

The Zen of Python Python之禅
Beautiful is better than ugly. 优美胜于丑陋
Explicit is better than implicit. 明了胜于晦涩
Simple is better than complex. 简洁胜于复杂
Complex is better than complicated. 复杂胜于凌乱
Flat is better than nested. 扁平胜于嵌套
Sparse is better than dense. 间隔胜于紧凑
Readability counts. 可读性很重要
Special cases aren’t special enough to break the rules.Although practicality beats purity. 即便假借特例的实用性之名,也不可违背这些规则
Errors should never pass silently.Unless explicitly silenced. 不要包容所有错误,除非你确定需要这样做
In the face of ambiguity, refuse the temptation to guess. 当存在多种可能,不要尝试去猜测
There should be one-- and preferably only one --obvious way to do it. 而是尽量找一种,最好是唯一一种明显的解决方案
Although that way may not be obvious at first unless you’re Dutch. 虽然这并不容易,因为你不是 Python 之父
Now is better than never.Although never is often better than right now. 做也许好过不做,但不假思索就动手还不如不做
If the implementation is hard to explain, it’s a bad idea.If the implementation is easy to explain, it may be a good idea. 如果你无法向人描述你的方案,那肯定不是一个好方案;反之亦然
Namespaces are one honking great idea – let’s do more of those! 命名空间是一种绝妙的理念,我们应当多加利用

列表

列表和C++ 里面的数组是比较相似的,Python里面,列表是线性且连续的,也就是说,不存在两个元素之间有空元素,所以这样就让Python在实现各种操作的时候简单了很多,但是也感觉可操作性就大大降低了,并没有C++的数组灵活。

列表在使用之前,必须声明一个空列表,如a=[]。这样才能实现下一步操作。


Python添加新元素的方法是使用append()函数和insert()函数。

append 「附加,增补」

insert 「插入,嵌入」

所以顾名思义,append是在列表末尾增加一个新元素

1
2
3
a=["Xorex"]
a.append(" is best!")
print(a)

输出结果就是[‘Xorex’,’ is best!’]

insert是在列表中间添加元素,格式:insert(下标,元素)

1
2
3
4
5
6
7
a=[]
a.append(1)
a.append(2)
a.append(3)
print(a)
a.insert(0,'Number')
print(a)

这样输出结果就分别为,[1, 2, 3] 和 [‘Number’, 1, 2, 3],Numer被插入到了下标为0的位置,其他元素往后移动一位。


如果要修改某个下标的元素就直接 a[下标]=元素 ,即可。


如果要删除列表里的元素,那么有下面几种方法:

  1. 使用del删除,如果你已经得知元素下标,可以这样写del a[0],这样a[0],也就是a列表里面的第一个元素就被删除了。

  2. 使用pop()删除,pop()可以删除制定位置元素并返回删除的元素值,如print(a.pop(2))就会删a列表里面第三个元素并返回删除的元素值,然后输出它。如果你不写弹出下标,那么就会默认删除最后一个元素,并返回最后一个元素的值,有点类似于堆栈,而pop的意思就是弹出。

  3. 使用remove()删除元素,a.remove(要删除的元素)就可以删除掉列表中所有为Xorex的元素,如果有多个元素都是Xorex,那么默认删除第一个元素,后面的Xorex保持不变。如果要删除全部,需要用循环不断验证,删除。


对列表中元素进行排列,有以下几种方法。

sort()进行从小到大排列,并更改列表里面的元素顺序,如果想要从大到小,那么就需要在函数里面添加参数sort(reverse=true)

reverse 「颠倒,使翻转」

而同样是排列的sorted()函数作用和sort()是一样的,不同的是sorted()只会返回排列好的列表,而不会更改原来列表里面的元素顺序。

注意 如果单独使用reverse()函数对列表进行更改的话,并不会排序,只会将列表元素顺序反过来。

sort()sorted()其实是支持自定义排序的,sort(cmp,key,reserve) 其中cmp代表着排序规则,key代表着参与排序的元素,reserve代表着是升序排序还是降序排序。


确定列表长度可以使用len()函数,如len(a)就会返回列表a的长度。


range 「一系列,范围」

range()可以生成一系列的数字,range(5)是生成从04的五个数字,而range(1,6)是生成从16-1的五个数字。最后range(1,11,2)代表着从1开始,不断加2输出,直到小于等于11-1

如果需要得知一个列表中的最大值,最小值,总和,可以使用min(a) max(a)sum(a)


列表循环的新方法

1
2
a=[x**2 for x in range(1,11)]
print(a)

这样生成的就是从110的平方了。


列表的复制中,如果使用b=a使列表a的值赋给了列表b。那么实际上ab就已经是同一个列表了。也就是意味着如果你更改列表a的值,那么列表b的值也会改变。

那么如何避免上面的情况呢,就需要这样来复制:b=a[:]也就是一个一个把a的值给b,这样ab就是两个不一样的列表了!


列表是可以使用二维,或二维以上的列表,具体实现方法就是俄罗斯套娃一样,列表里面套列表(元组,字典也是可以的),下标的表示方法和C++一样,比如下面的代码:

1
2
3
4
a=[[[1,'HEXO'],2,3],4,5,6]
b=['Xorex',2,3]
a.append(b)
print(a[0][0][1])

最后输出的结果就是HEXO

元组

元组就是不能修改的列表,从Python里面有元组就可以看出来,Python真的是一个非常实用化的语言,而并非追求灵活和性能的C++。(实测Python的速度超级慢,同样的计算量大概需要耗时是C++的二十倍到一百倍)

条件语句

Python里面的if语句和C++里面基本上是一样的,不同之处就是在判断多个满足条件的时候,Python使用的是英文andor等等,而并非符号语言。

其次Python支持判断一个元素是否在一个列表里面,使用in即可,比如:

1
2
3
a=[1,2,3,4]
if 1 in a:
print("Yes!")

这样就会判断1在列表a中,所以就返回了true值,输出了Yes!

字典

字典是Python完全不同于C++的一种变量类型。可以说是语言自带的Hash,非常强大,非常实用!

首先实用字典之前需要先声明一个空字典a={}

字典数据的添加不需要函数,直接a['Xorex']="The Best Coder!,就添加了Xorex-The Best Coder!的一个键-值对,在访问a['Xorex']的时候,返回的值直接就是The Best Coder!

需要删除使用del格式即可:del a['Xorex']这样这个键值对就被删除了。


和列表一样,字典也可以实现多维度操作,原理就是俄罗斯套娃,字典里面随便套,一层套一层,下标和C++一样,比如下面的代码:

1
2
3
4
a={1:1,2:{1:{1:1,2:2},2:2}}
b=['Xorex',2,3]
a[2][1][2]=b
print(a[2][1][2][0])

输出结果就是Xorex


字典和列表一样,也可以使用for循环来把所有元素遍历一遍,比如下面的代码:

1
2
3
4
5
a={1:1,2:{1:{1:1,2:2},2:2}}
b=['Xorex',2,3]
a[2][1][2]=b
for i in a[2]:
print(i,a[2][i])

输出结果就是:

1
2
1 {1: 1, 2: ['Xorex', 2, 3]}
2 2

输入

Python默认让用户输入的都是以字符串的形式存储在变量里面,如果需要不同的数据类型,那么就需要强制转换,写法和C++一样:

1
2
3
a=int(input())
a=a+1
print(a)

输出的结果就是你所输入的值加一。


split()可以实现像cin一样的读入一行的不同数据,原理就是将一行字符串以空格分开,单独存储在一个列表里面。

1
a,b=input().split()

等价于

1
cin>>a>>b;

上面使用split()的时候,一定要保证一行里面只有两个数据,不然就会出现ValueError,如果不放心的话可以使用try-except代码块或者直接将一行分离的数据存储在列表中。

split「分裂,分离」

具体用法

循环

PythonC++一样,有两种循环方式,一种是for另一种是while

详情:循环语句

但是这里需要注意的是,如果在使用for循环来遍历整个列表的时候,就不应该修改这个列表,否则就会出现一些奇奇怪怪的错误,这个时候就应该使用while循环。


同时Python也带有continuebreak语句,使用方法和C++一模一样。

注意Python里面的TrueFalse首字母是大写的!

函数

格式:

1
2
3
def name(variable=0):
then work
return something

其实Python函数的各种功能个C++的差不多,但是需要注意的是,当你在函数里面修改传递的参数的时候,如果参数是数字,字符串的话,是不会影响函数实参的值的。但是如果你传递进去的参数是列表和字典,那么当你修改形参的值的时候,实参的值也会变,这点是必须要注意的,比如下面代码:

1
2
3
4
5
a=[1,2]
def Change(b):
b.append(3)
Change(a)
print(a)

最后输出的列表a的值是[1,2,3],即使你修改的是b的值,那么实参也会跟着改变,如果想要实参不会跟着改变,那就需要这样写:

1
2
3
4
5
a=[1,2]
def Change(b):
b.append(3)
Change(a[:])
print(a)

传进去一个被复制下来的列表,这样修改函数里面的列表的时候就不会连带着一起修改实参的数据了。然后上述代码的输出结果就是[1,2],可见实参a列表并没有被跟着一起修改。

模块

Python的模块,其实和C++里面的库差不多,就是一个各种函数的集合体,不过不需要你在主代码里面编写函数,这些函数存储在其他文件里面,你直接通过调用其函数所在的模块,就可以间接调用这个函数。

模块是一个独立的文件,拓展名是.py,里面直接留各种函数就行了,比如我们开一个模块叫做Xorex.py,里面包含三个函数。

文件Xorex.py

1
2
3
4
5
6
def The_True():
print("Xorex is the best!")
def The_False():
print("Xorex is not the best!")
def Xorex():
print("Xorex is a programmer!")

然后我们就可以在其他代码里面调用这个函数。

1
2
3
4
5
import Xorex #使用import来导入整个模块Xorex
Xorex.The_True()
Xorex.Xorex()
Xorex.The_False()
#调用模块Xorex里面的三个函数

结果就是输出了:

「世界真理」:Xorex is the best!

「真实身份」:Xorex is a programmer!

「世界谎言」:Xorex is not the best!

import 「引进,进口」

import导入的是整个模块里面的所有东西,整个模块会全部添加到自己的程序里面,如果不想全部都导入,而是导入特定的函数,那么就需要这样写:

1
2
3
4
from Xorex import Xorex,The_True
Xorex()
The_True()
The_False()

或者不导入整个模块,导入全部的函数,并且函数的调用和上面是一样,

1
2
3
4
from Xorex import *
Xorex()
The_True()
The_False()

这两种导入方式在调用函数的时候不需要写模块的名字,只需要像直接调用本地函数一样调用就好了。而且Python还支持重新命名,如下把Xorex模块里面的The_True()重新命名为TT()

1
2
from Xorex import The_True as TT
TT()

模块支持将一个模块里面的函数导入到另外一个模块里面,只要在模块前面写上import语句就行了,实际操作可以参考下面class从一个模块导入另一个模块的操作。

class类

类就是C++里面加强版的结构体,或者说结构体是特殊的类,下面是类创建的格式:

1
2
3
4
5
6
class Name:
def __init__(self,First,Last):
self.First_Name=First
self.Last_Name=Last
Xorex=Name('Tempest','Xorex')
print(Xorex.First_Name,Xorex.Last_Name)

这样就实现了类似于C++里面结构体的功能了,定义“结构体”名字为NameName里面有两个子元素,分别为First_NameLast_Name。需要“声明”一个“结构体”类型的变量的时候,只需要另此变量等于所定义的结构体就行了,需要为变量赋值的话可以以函数的形式传递参数,其中self参数不需要传递,Python会自动向self传递目前对象(Xorex)的地址,也就是说,调用Xorex=Name('Tempest','Xorex')的时候,self在里面就相当于Xorex,也就是说,self.First_Name=First就会等价于Xorex.First_Name=First,因为self被传入了Xorex的地址。

__init__函数(方法)是class里面自动运行的名字,如果在定义class的时候,添加有一个叫做__init__的函数(方法),那么在声明class类型变量的时候会自动运行这个叫做__init__的函数(方法)。你可以用__init__函数(方法)在声明class类型变量的时候,直接就赋值,因为class里面的变量是不允许没有初始值的。

当然如果你想声明以后再给class里面的变量赋值的话,可以这样写:

1
2
3
4
5
6
7
class Name:
First_Name=''
Last_Name=''
Xorex=Name()
Xorex.First_Name='Tempest'
Xorex.Last_Name='Xorex'
print(Xorex.First_Name,Xorex.Last_Name)

输出的结果和上面的代码是一样的。


classC++里面结构体厉害的地方在于,class功能更多,比如里面可以内置函数(方法),但是这个标准名称叫方法,下文也不再以函数称呼,而是方法。

同样和上面定义的方法__init__()一样,所有的class内部定义的方法都需要一个参数,用来记录当前对象的地址,程序员们约定俗成使用self作为此参数,位于所有形参的前面,即使方法不需要传递参数,那么还是需要self来记录地址的。

比如我们可以实现一个class内部的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class bilibili:
def Cheer(self,Name):
print(Name+",Let's cheer for bilibili!")
def Coin(self,Number):
if Number == 1:
print("You have successfully thrown a coin!")
elif Number == 2:
print("You have successfully thrown two coins!")
else:
print("Sorry,You can't throw this coins!")
Xorex=bilibili()
Xorex.Cheer("Xorex")
Xorex.Coin(-1)
Xorex.Coin(2)

这里首先声明一个自定义bilibili类型的变量Xorex,然后调用bilibili里面的方法。格式:Variable.Function(Parameter/None)


class是可以继承的,「继承」字面意思,即使用其他class的功能(比如其他class定义的方法)

下面就是一个class继承上面三个class的各种功能的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class First:
def __init__(self):
print("First")
class Second:
def __init__(self):
print("Second")
class Third:
def __init__(self):
print("Third")
class Son(First,Second,Third):
def __init__(self):
First.__init__(self)
Second.__init__(self)
Third.__init__(self)
Xorex=Son()

Son继承了上面的FirstSecondThird的功能,然后被Son的默认执行方法执行了使用前面三个class的默认执行方法的命令。最后的输出结果:

1
2
3
First
Second
Third

class和函数一样,支持存储在模块中,从外部进行调用,两者格式是一样的,都是通过import来实现。

新建一个叫Xorex.py的模块,里面存入需要的class:

1
2
3
4
5
6
7
8
9
class First:
def __init__(self):
print("First")
class Second:
def __init__(self):
print("Second")
class Third:
def __init__(self):
print("Third")

然后在当前代码调用Xorex模块里面定义的class

1
2
3
4
5
6
7
#导入整个模块,需要调用前指明Xorex模块
import Xorex
class Son(Xorex.First,Xorex.Second,Xorex.Third):
def __init__(self):
Xorex.First.__init__(self)
Xorex.Third.__init__(self)
Xorex=Son()
1
2
3
4
5
6
7
8
#只导入需要的class,或者全部class,不需要指明Xorex模块
from Xorex import First,Second,Third #指名导入class
from Xorex import * #导入全部class
class Son(First,Second,Third):
def __init__(self):
First.__init__(self)
Third.__init__(self)
Xorex=Son()

class支持不同模块之间的相互导入,如果将导入看做是代码复制的话其实就很好理解了,使用在模块前面加上import语句就行了。注意的是import Name格式导入的是整个模块所有的内容,所以在模块的相互导入的时候不能使用:import Name格式,而应该使用from XXX import XXX导入类。在主程序里面调用模块的时候不受限制,可以使用上面的两种导入方法。

文件处理

读取文件里面的数据格式,这里使用with open('XXX') as XXX的写法,可以不用管文件关闭的问题,Python会执行完with句型后面的代码之后关掉文件。而这里open()里面填写的是文件名称,后面的XXX是一个变量,用来存储你打开文件的地址。文件一旦关闭,存储的文件地址也就无法使用了。

那么如何获得文件里面的数据呢,需要使用read()来以字符串的形式返回文件里面的所有内容。如果需要分开处理,直接上split()大法。

1
2
3
4
5
6
7
8
9
Data=[]
Path='D:\Xorex\python\data.in'
with open(Path) as Xorex:
Data=Xorex.read().split()
n=int(Data[0])
m=int(Data[1])
del Data[0]
del Data[0]
print(n,m,Data)

这样我们就得到了文件data.in里面所有的数据了,如果文件data.inPython程序在同一个目录里面,那么就可以简写了,比如,可以删除Python程序目录的地址内容,如果data.inPython程序同目录的Data文件夹里面,那么Path路径可以更改为:Path='data\data.in'

当然我们可以不使用read()来读取整个文件里面的内容,我们可以一行一行的读取,需要用到for循环:

1
2
3
4
5
Data=[]
Path='data.in'
with open(Path) as Xorex:
for line in Xorex:
print(line.rstrip())

这样每一行的数据都会以字符串的形式被存储在line这个变量里面,使用rstrip()函数是为了删除不必要的空行。


使用readlines()函数可以把每一行数据单独的存储在一个列表里面,比如:

1
2
3
with open('data.in') as Xorex:
Data=Xorex.readlines()
print(Data)

这样输出的就是一个列表了。


关于文件输出

格式和输入基本一样,不过需要增加一个参数'w',表明是输出,如果不写'w'默认是文件输入。

1
2
with open('data.out','w') as Xorex:
Xorex.write("Xorex is the best coder!")

运行程序会生成一个名称为data.out的文件,里面就包含这一句话:Xorex is the best coder!

使用'w'来输出数据会使被输出的文件清空,如果你不想原来data.out的数据被清空(覆盖),那么你就可以使用参数'a',是add的意思,不改变文件里面的内容,直接在后面加上要输出的东西。

注意这里write只能输出字符串,如果想要以其他形式输出,那么可以使用json模块规范化输出。


这里再介绍一种文件输出更好的写法:

1
2
Xorex=open('data.out','w')
Xorex.write("Xorex is the best coder!")

注意这里Xorex是特定的指向data.out这个输出文件可以再程序里任何位置调用Xorex.write()函数,并且open里面还有很多参数,比如Python3 open()函数

异常

Python程序遇到运行错误的时候,我们当然并不想让这个程序就这样不知所措的停止运行,所以try-except语句便诞生了,可以定向处理错误,知道有这个东西就行了,估计很少用到(目前)

1
2
3
4
5
6
7
a,b=input().split()
a=int(a)
b=int(b)
try:
print(a/b)
except ZeroDivisionError:
print("You can't divide by zero!")

上面代码里面,程序会先尝试运行try后面的,如果出现了except后面跟随的异常ZeroDivisionError,也就是除零错误,那么就会执行except下面的代码,也就是输出错误原因。如果想要出现错误的时候程序什么都不做,那么在except下面写上pass即可。

存储数据

模块json可以将程序里面的数据单独存储下来,即使程序结束运行数据仍然存在。json是可以跨平台使用的,所以子啊使用json模块的时候,一定要记得使用import将其导入到代码里面。

json.dump(data,file_object)函数需要接受两个参数,一个是需要存储的数据data,另外一个就是需要存储的目标文件的地址file_object,一般这个地址在使用with open(file) as file_object的时候,已经吧file的地址存储在了file_object里面。

1
2
3
4
import json
Numbers=[1,2,3,4,5,6]
with open('data.out','w') as Xorex:
json.dump(Numbers,Xorex)

这样Numbers里面的数据就会以列表的形式存储在data.out文件里面了。打开data.out文件,你就会发现里面有:[1,2,3,4,5,6]

dump:「丢弃,倾倒」


我们如果需要从规范的json格式的数据文件里面读入数据,就不能使用read()了,因为这样读进去的是字符串而并非列表,字典等格式化数据。这里就需要使用json里面的load函数。

1
2
3
import json
with open('data.in') as Xorex:
Numbers=json.load(Xorex)

这样变量Numbers里面就存储了来自于data.in文件里面的标准数据了。如果data.in里面没有存储数据就去读取,那么就会报错,为了避免这样的情况,我们可以使用try-except语句来判断是否出现异常,并写出应对异常的代码。

最后总结:

至此,Python的基础学习暂时告一段落,开始Python实战内容,加油吧!