Python特性
- 跨平台的程序设计语言
- 解释性语言,不编译
- 交互语言可以直接执行代码
- 面向对象语言
面向过程是分析解决问题所需的步骤,然后用函数一步一步地实现这些步骤。使用时,可以逐个调用;
面向对象是将构成问题的事务分解为每个对象。建立对象的目的不是完成一个步骤,而是描述解决问题的整个步骤中事物的行为。
面向过程: 优点:性能高于面向对象,因为类调用需要实例化,成本大,资源消耗大;如单片机、嵌入式开发、 Linux/Unix性能是面向过程开发的最重要因素。 缺点:不易于维护、重用、扩展
面向对象: 优点:易于维护、易于复用、易于扩展。由于面向对象具有包装、继承和多态性的特点,可以设计低耦合系统,使系统 更灵活,更容易维护 缺点:性能低于面向过程
下载安装
淦哦,py3.9居然在Windows7上面跑不了
python自带文件说明
- IDLE:简单开发环境
- Python:互动命令行程序
- manuals:官方技术文件
- module docs:已安装的模块文档
要写代码在IDLE写在里面
pycharm
一个更好的IDE,去官网下来用就行,感觉社区版的应该够用
具体操作细节属于肌肉记忆,不细说
函数,转义字符等基础
在黑框里输出一些东西
- 加上
type(X)
可输出变量X的类型 - 加上
id(X)
可输出变量X地址
open
将一些东西输出到文件中,可和print一起乱用,返回指针
fp=open('location','mode') print(XX,file=fp) fp.close
其中的mode有:见链接
input函数
输入函数,可以给提示语,比c方便多了
运算符
顾名思义,详见链接
转义字符
见链接
ASCII,Unicode
它是将01与字母连接起来的手表
Unicode是在ASCII之后的事情可以表达几乎全世界的字符。我记得我写博客的时候需要把那个写出来。TXT文件按照UTF-这一定是8的原因。
标识符和保留字
保留字实际上是一些py有特殊含义的字符不能乱用,比如显然不能用def命名一个变量什么的
标识符是你给变量的名字,严格区分大小写(都是这样)
变量
变量是啥
放东西…
(不知道怎么解释。太基础了。)
不过python里面有一个很舒服的东西,就是变量不需要定义类型,它收到的是什么类型,比c爽多了
变量的组成
变量由三件事组成:
- id:变量内存地址
- type:变量的类型
- value:储存在变量中的东西
变量赋值
等号是赋值
赋值可以重复很多次(好像很明显)
数据类型
int:整数
- 十进制:默认的那种
- 二进制:十进制前加0b来转义
- 八进制:十进制前加0o来转义
- 十六进制:十进制前加0x来转义
float:浮点数
解决浮点数不准确的方法:
引入模块如下:
from decimal import Decimal
调用时:
print(Decimal('1.1') Decimal('2.2'))
bool:布尔类型
false=0 true=1
bool可转为int,所以不要太在意
str:字符串类型
单双引号字符串必须在一行
连续多行可分布三引号
转换数据类型
str(X)
:将X转换为字符串类型 int(X)
:将X转换为整数类型 float(X)
:将X转换为浮点数类型
但是不要乱转,有些是不能转的
注释
用#
单行注释,"""
多行注释
编码声明可在开头规定:
# coding:gbk
(ascii) # coding:utf-8
(Unicode)
控制程序的组织结构
选择结构
if,elif,else
if XXX: D something
elif XXXX
Do something
elif XXXX
Do something
else
DO something
条件表达式
if XXX:
Return something A
else
Return something B
等价于
Return something A if XXX else Return something B
其实就和cpp里面问号表达式一样:
(XXX?(Return something A):(Return something B));
感觉cpp里面的装逼要厉害些哈哈哈
pass语句
占位置,用在需要写但还不知道写啥的时候
循环结构
range
生成一个整数序列[start,stop),且每两个数之间差为step
range(start,stop,step)
可以用如下方式来看序列里面有没有某一个数:
r=range(1,10,2)
print(5 in r)
>>>>True
>print(5 not in r)
>>>>false
while
当型语句,当满足while后面的条件后继续循环内的语句
while XXX:
do XXXXX
for in循环(遍历)
字符串和序列(range)是可迭代变量
for循环的语法如下:
遍历字符串
for s in "international":
print(s)
>>>
i
n
t
e
r
n
a
t
i
o
n
a
l
其实就是一个一个字母的拿出来然后赋值给s变量
遍历序列
for s in range(10):
print(s)
>>>
0
1
2
3
4
5
6
7
8
9
其实就是一个一个值拿出来然后赋值给s变量
没有变量的无灵魂遍历
for _ in range(10):
print("hiahiahiahiahiahiahia\n")
>>>
hiahiahiahiahiahiahia
hiahiahiahiahiahiahia
hiahiahiahiahiahiahia
hiahiahiahiahiahiahia
hiahiahiahiahiahiahia
hiahiahiahiahiahiahia
hiahiahiahiahiahiahia
hiahiahiahiahiahiahia
hiahiahiahiahiahiahia
hiahiahiahiahiahiahia
break
就是从循环中强制退出的语句
只要运行到这一句那就退出当前的循环喽
continue
只要运行到这一句就不管后面的代码直接从循环头头开始重新走一遍
else
else不仅仅可以和if一起用,还可以和while,for一起用
只是我感觉好像else和while,for一起用很奇怪,可能是我cpp打多了吧
简单数据结构
列表
其实就是c++里面的数组,里面可以一个个的存东西
(感觉说了一堆废话)
不过python里面的列表可以存不同类型的数据,和c++里面的数组只能够存数字或字符串有很大的区别,py果然优秀一些
并且这个列表不用管空间,有数据就放就行,不会想C++一样因为手残空间开小了导致数据溢出然后暴掉,就很舒服
列表基本定义和操作
liebiao=['hello','world',98]
liebiao2=list(['hello','world',98,'world'])
print(liebiao)
print(liebiao2)
print(liebiao[1])
print(liebiao[-1])
>
['hello', 'world', 98]
['hello', 'world', 98, 'world']
world
98
1
1
列表查询元素索引操作
liebiao2=list(['hello','world',98,'world'])
print(liebiao2.index('world'))
print(liebiao2.index('world',0,2))
>
1
1
列表切片操作
liebiao_name[start:stop:step]
,区间[start,stop),步长为step
liebiao=list(['hello','world',98,'ee','iede','hiahia',520])
print(liebiao[1:6:2])
print(liebiao[6:1:-2])
>
['world', 'ee', 'hiahia']
[520, 'iede', 98]
列表元素存在与否判断
用in
,not in
来判断
列表元素迭代
for var_name in list_name:
即可
列表元素的增加操作
list_name.append(A)
:在列表list_name末尾加一个元素A,很鸡肋的事情就是,如果A是一个列表,那么就会出现列表里面嵌套列表的情况,很活络但是不知道好不好
list_name.extend(A)
:在列表list_name末尾至少添加一个元素A,这个时候如果A是一个列表,就会把两个列表合并,把A怼在list_name后面
list_name.insert(pos,A)
:在列表的位置pos添加一个元素A
好像切片可以随便插入很多元素:
liebiao=list(['hello','world',98,'ee','iede','hiahia',520])
print(liebiao)
liebiao[1:1:1]=['lueluelue','abababa']
print(liebiao)
liebiao[2:4:1]=['250','520']
print(liebiao)
>
['hello', 'world', 98, 'ee', 'iede', 'hiahia', 520]
['hello', 'lueluelue', 'abababa', 'world', 98, 'ee', 'iede', 'hiahia', 520]
['hello', 'lueluelue', '250', '520', 98, 'ee', 'iede', 'hiahia', 520]
列表元素的删除操作
list_name.remove(A)
把第一个A从列表中删掉
list_name.pop(pos)
把位置为pos的元素从列表中删掉,如果pos没有定义,就删除最后一个元素
当然切片也可以大量的删除元素,如果想要把切后的元素直接赋给原列表,可以:
list_name[start,stop,step]=[]
list_name.clear()
清空列表中的所有元素
del list_name
把列表整个删了
列表元素的修改操作
直接赋值可以list_name[X]=A
也可以切片,见上
列表的排序操作
太舒服了,直接快排,想起了当年用cpp手写快排的时光…
list_name.sort(reverse=False)
升序排序,默认
list_name.sort(reverse=True)
降序排序
或者可以用内置函数来产生一个列表对象
list_name2=sorted(list_name,reverse=True)
,降序排列,放到list_name2里面
列表生成式
用for循环一句话就可以搞一个列表出来,有点意思
list_name=[i*X for i in range(start,stop,step)]
比如:
list_name=[i*1 for i in range(1,10,1)]
print(list_name)
list_name=[i*4 for i in range(1,10,1)]
print(list_name)
>
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[4, 8, 12, 16, 20, 24, 28, 32, 36]
字典
字典是啥
一个无序的序列,可变,每个元素由和构成,叫,感觉这个数据结构过于方便和高级了,咋实现的啊…
哦原来用的是hash函数啊,好高级,字典树?不知道
感觉字典树应该可以实现这个功能,可以试一下诶
那这东西占的空间不是大的飞起来,天哪
字典的创建
dic_name={'haha':22,'heaha':2322,'hahar':222,'harha':232}
dic_name=dict(name='jack',age=20)
字典元素的获取
dic_name={
'haha':22,'heaha':2322,'hahar':222,'harha':232}
print(dic_name['haha'])
print(dic_name.get('haha'))
print(dic_name.get('hahaiii',7373))
>
22
22
7373
用字典内置的get函数可以避免找不到对应的键从而导致程序炸掉,这种情况下get函数返回一个None值
如果在get后面放一个数字,那么如果没有插到对应的键,就会把这个数字返回来
字典元素存在与否的判断
dic_name={
'haha':22,'heaha':2322,'hahar':222,'harha':232}
print('haha' in dic_name)
print('haha' not in dic_name)
>
True
False
就用in,not in判断就行
字典元素的删除
dic_name={
'haha':22,'heaha':2322,'hahar':222,'harha':232}
del dic_name['haha']
print(dic_name)
>
{
'heaha': 2322, 'hahar': 222, 'harha': 232}
用del命令即可
字典元素的新增和修改
dic_name={
'haha':22,'heaha':2322,'hahar':222,'harha':232}
dic_name['lueluelue']=520250
print(dic_name)
dic_name['lueluelue']=520
print(dic_name)
>
{
'haha': 22, 'heaha': 2322, 'hahar': 222, 'harha': 232, 'lueluelue': 520250}
{
'haha': 22, 'heaha': 2322, 'hahar': 222, 'harha': 232, 'lueluelue': 520}
获取字典的视图
获取所有的键:用内置函数Keys=dic_name.keys()
获取所有的值:用内置函数Value=dic_name.values()
获取所有的键值对:用内置函数Items=dic_name.items()
,返回的是元组
字典元素的遍历
用for:
dic_name={
'haha':22,'heaha':2322,'hahar':222,'harha':232}
for A in dic_name:
print(A)
print(dic_name[A])
字典生成式
内置函数zip:
dic_name={Key_list:Value_list for Key_list,Value_list in zip(Key_list,Value_list)}
Name=['A','B','C','D']
scores=[1,1,0,0,-1]
dic_name={
Name:scores for Name,scores in zip(Name,scores)}
print(dic_name)
>
{
'A': 1, 'B': 1, 'C': 0, 'D': 0}
如果两个列表内容数量不同,以少的那个为准
元组
元祖是啥
是一个不可变序列,没办法增删改
据说用不可变序列有利于防止把操作对象搞混
当然如果元组里面存一个列表这种可变序列的话,这些可变序列是可以修改的,很有意思
元组的创建方式
三种等价方式
t=('P','h',99)
t='P','h',99
t=tuple(('P','h',99))
如果元祖里面只有一个元素,要这样写:
t=('p',)
元组的遍历
t=('P','o',2,3,4,4,24)
for i in t:
print(i)
就可以实现遍历(好像一般遍历都是用for循环就行吧)
集合
集合是啥
是没value的字典,也是用hash来搞的,这个集合里面没有重复的元素,这可是数学里面的集合的基本性质
集合的创建
两种等价方式
s={
1,2,2,3,2}
s=set({
1,2,2,3,2})
集合元素判断
in或not in就可以了
集合元素的增加操作
s.add(x)
,x加入集合s
s.update(A)
,s中加入集合或列表或元组A
集合元素的删除操作
s.remove(x)
:删除一个指定元素x,如果没有就报错
s.discard(x)
:删除一个指定元素,如果指定元素不存在不报错
s.pop()
:一次删除任意一个元素(好奇怪的东西)
s.clear()
:清空集合
集合之间的关系
判断两个集合一样或不一样:A==B
,A!=B
判断A是否是B的子集:A.issubset(B)
判断A是否是B的超集:A.issuperset(B)
判断AB是否有交集:A.isdisjoint(B)
,有交集返回false
,否则返回true
集合的数学操作
s1.intersection(s2)
,s1 & s2
都是求交集
s1.union(s2)
,s1 | s2
都是求并集
s1.difference(s2)
,s1 - s2
都是求差集
s1.symmetric_difference(s2)
,s1 ^ s2
都是求对称差集
集合生成式
把列表生成式中的方括号变成花括号就行
s={i for i in range(1,10,2)}
字符串
不可变的字符序列
字符串的声明
单双三引号都可以的
字符串的驻留机制
对于多个实际内容相同的一个字符串,python不会多次占空间,只在内存里面搞一份,这就叫驻留,很省空间
但是驻留也有条件
- 字符串长度为0,1时
- 只有字母数字下划线的字符串
- 一开始就一样的字符串(后面加成一样的不算)
- [-5,256]之间的数字
可以强制驻留,引入:import sys
即可
pycharm优化了这种情况,可以不用引入sys就可以驻留
字符串的常用操作
字符串的查询
s.index('substr')
:查找子串substr第一次出现的位置,如果子串不存在,就报错
s.rindex('substr')
:查找子串substr最后一次出现的位置,如果子串不存在,就报错
s.find('substr')
:查找子串substr第一次出现的位置,如果子串不存在,就返回-1
s.rfind('substr')
:查找子串substr最后一次出现的位置,如果子串不存在,就返回-1
字符串的大小写转换操作
s.upper()
:把字符串中所有字母转化成大写字母
s.lower()
:把字符串中所有字母转化成小写字母
s.swapcase()
:把字符串中所有小写字母转化成大写字母,所有大写字母转化成小写字母
s.capitalize()
:把第一个字母转换为大写,其余的字符转化为小写
s.title()
:把字符串中每个单词的第一个字母转换为大写,其余的字符转化为小写
字符串的内容对齐方法
s.center()
:居中对齐,第一个参数指定宽度,第二个参数指定填充符,可选,默认空格。如果设置宽度小于实际宽度就返回原字符串
s.ljist()
:左对齐,第一个参数指定宽度,第二个参数指定填充符,可选,默认空格。如果设置宽度小于实际宽度就返回原字符串
s.rjist()
:右对齐,第一个参数指定宽度,第二个参数指定填充符,可选,默认空格。如果设置宽度小于实际宽度就返回原字符串
s.zfill()
:右对齐,左边用0填充,只收一个参数指定字符串的宽度。默认空格。如果设置宽度小于实际宽度就返回原字符串
字符串的劈分操作
s.spilt(sep='X',maxspilt=A)
:从左开始劈,默认以空格为标志劈,返回一个列表。可用参数sep来定劈分符,用maxspilt来定最大劈分次数
s.rspilt(sep='X',maxspilt=A)
:从右开始劈,默认以空格为标志劈,返回一个列表。可用参数sep来定劈分符,用maxspilt来定最大劈分次数
字符串的判断操作
s.isidentifier()
:判断s是不是合法的字符串
s.isspace()
:判断s是否全部是空白字符组成
s.isalpha()
:判断s是否全部由字母组成
s.isdecimal()
:判断字符串是否全部由十进制数字组成
s.isnumberic()
:判断s是否全部由数字组成
s.isalnum()
:判断s是否全部由字母和数字组成
字符串的替换和合并
s.replace('A','B',X)
:字符串的替换,用B换A,换X次
s.join()
:将列表或元组中的字符串合并为新的一个字符串,感觉这个函数很奇怪…
字符串的比较操作
>,>=,<,<=,==,!=
都可以用来相应的比,比的时候从前往后一个一个的比,比的实际上就是ascll码或者什么码,就酱
字符串的切片操作
切片涂奶酪,真香
就和列表切片一个格式:
s='hello Java'
s1=s[:5:1]
s2=s[6::1]
s3='!'
print(s1+s3+s2)
>
hello!Java
格式化字符串
用%,{},{var}
来做占位符都ok
name='popoi'
age=1231
print('my name is %s,%d years old' % (name,age))
print('my name is {0},{1} years old'.format(name,age))
print(f'my name is {
name},{
age} years old')
>
my name is popoi,1231 years old
my name is popoi,1231 years old
my name is popoi,1231 years old
%Xd
:X是数字前面的宽度 %.Xlf
:X是保留小数的位数
这些细节比较杂,可以去网上找一些详细的资料,看着用就应该没问题了
字符串的编码转换
可以用encode
和decode
来编码和解码,也就是把字符串搞成GBK或者UTF-8用s.encode(encoding='GBK')
或者s.encode(encoding='UTF-8')
,把GBK或者UTF-8搞成字符串用s.decode(encoding='GBK')
或者s.decode(encoding='UTF-8')
函数
函数是啥
太基础,没法解释
函数的创建
def Name(canshuA,canshuB...):
do something
return X
其中参数canshuA,canshuB
(这个是形参)等等都是可以在def语句那里赋一个初值的,避免没有值的时候出现bug
函数的返回值
如果返回多个值,结果就是元组类型
函数参数
可变数目的参数
这个挺好用的诶
如果只是单个元素(个数可变的位置参数)的话可以这样:
def fun(*args):
return args
这个时候如果往fun函数里面输入多个值,args就会以一个元组的形式返回
如果有多个元素可以搞成字典的形式(个数可变的关键字参数):
def fun(**args):
return args
print(fun(a=10,b=34,c=429))
>
{
'a': 10, 'b': 34, 'c': 429}
可变的未知参数只能够有一个哦,写多个要遭起
python的异常处理机制
debug这个东西…噩梦啊
除了一般的贱贱的手法比如加调试信息,加断点之外,还有这些新东西可以试试
try…except…else结构
try:
do A
except BaseException as e:
do B
else:
do C
finally:
do D
其中A部分就是可能出现bug的代码,B部分就是出现bug后要干的事情,BaseException那里可以写可能出现的错误,如果不知道会出现什么错误就写BaseException来网罗所有错误,e就是给这个错误取的名字,起到简略代码量的作用,C部分就是没出锅要干的事情,D就是无论如何都要在最后干的事情(这个好像没什么必要吧突然感觉)
有意思
类
类的创建
class Class_name:
pass