python
安装python解释器及代码编辑器
pycharm
表示独立的python虚拟环境,不同项目会使用不同的python库,不同解释器版本,适合程序员做多个项目以及团队合作。新手不需要往里面放任何东西,也不要删任何东西。
编程语法
打印
print("hello")//单引号和双引号都可以,这里面是字符串,不需要分号
.py是python文件的后缀
好几个字符串可以用+连接起来
字符串里的双引号单引号要注意配对,外双内单或内单外双都可以,或者在前面加转意字符\
想打印换行使用\n或者\,或者三个双引号圈住的内容里的换行是可识别为内容换行,有助于打印跨行多的内容
退出代码为0,是正常运行退出
命名规则
赋值操作
变量名只能是英文字符、数字、下划线。数字不能作为变量名的开头
my_phone = "199999"
My_email = my_phone
下划线命名法:字符全部是小写,单词之间用_隔开:user_age
驼峰命名法:单词用首字母大写分隔:UserAge
大小写敏感,不要使用关键字
数字运算
使用math函数库
import math
result = math.sin(30)
print(result)
优先级:() 乘方** */ ±
乘方** :2的3次:2 ** 3
求开方可以:math.sqrt()或者是3** (1/2)
注释
#在开头放可以注释
多行注释快捷键是 command+‘/’或者是三引号
#这是一段注释
"""看不到我看不到我
看不到我嘿嘿"""
数据类型
字符串为str
可以通过len()函数来计算字符串的长度
空格和字符串是一个长度,但是完整的转义字符才算一个长度
print("hello"[3])//可以提取出第三个字符 这也是索引,但是第一个索引为0
真假类型bool:True False//记得首字母要大写
空值类型NoneType:None// 这不意味是0 也不是空字符串 也不是False,还没有确定变量具体值的时候可以先赋值为None
可以通过type函数返回该对象的类型
交互模式
python可以不解释完所有命令就执行
不需要创建任何python文件就可以运行,可以不通过print模式就可以看到变量对应的值。但是不保存热河代码和变量
在终端中输入 python 之后会出现三个尖括号>>>,则表示等待你输入的python命令
>>> a= “nihao”+“!”
>>> a
‘nihao!’
在命令行模式当中,需要print(2*3),但是在交互模式,只需要2 * 3
input
一律返回字符串。可以通过用一个变量来接收
若是想要数字类型,可以使用int(x);str(x)这种类似于强制转换
age = int(input("您现在的年龄是:"))
after_age = age + 10
print("您十年后的年龄是"+str(after_age)+"岁")
age = int(input("您现在的年龄是:"))
after_age = age + 10
print("您十年后的年龄是"+str(after_age)+"岁")
条件语句
比较运算符== != >= <=
if[条件]:
[执行语句]//一定要缩进,通过缩进来判断是否为同一段,而不是大,括号
else:
[执行语句]
study_index = int(input("我今天的学习时间为:"))
if study_index>5:
print("你今天表现真不错")
print("😄")#同一个缩进可以判断为是一个语句块
else:#注意冒号的存在
print("你还需要继续学习哦")
嵌套
根据缩进判断是哪一个分支›
elif!!!不是else if
逻辑运算
and与
or或
not不
列表
有点类似于c语言的数组:方括号,中间用逗号隔开,列表类型是可变的,字符串str整数int是可变的
list=["第一","第二"]
方法:
对象.方法名
函数:
函数名(对象)
eg:
s = "hello"
print(s.upper())
print(s)
这里的s.upper是变成大写输出,但是s字符串没有改变
list=["第一","第二"]
list.append("第三") #往列表尾部加元素
list.remove("第三") #删除列表尾部的元素
print(list)
显示的是:[‘第一’, ‘第二’, ‘第三’]
数组是可以变的,所以不需要赋值(如果是字符串想要被修改的话需要重新对该命名的变量进行赋值)
len函数:列表可以求长度,求出来的数字为列表里面内容的个数:
列表的索引从0开始,也可以直接对索引赋值,可以通过print()函数直接打印列表里的项
Max()
Min()
Sorted() #打印排序列表
字典
键:值
key:value
空用花括号表示
多个键值对用逗号圈住,冒号表示,逗号区分
contacts={"小明":"18",
"小黄":"19"}
可以通过键值来查找值
print(contacts["小明"])
但是键不能是可变的,也就是说不能是列表。但是python中的元组tuple是不可变又类似于列表的结构
元组用圆括号,所以append,remove函数不可用
字典是可变的,可以增加和删除键值对
contacts={"小明":"18",
"小黄":"19"}
contacts["小宝"]="20"#直接赋值即可
print(contacts["小宝"])
通过in查找是否存在
contacts={"小明":"18",
"小黄":"19"}
print( "小明" in contacts) #查找是否存在用 in,存在返回true,不存在返回False
print( "小宝" in contacts)
删除用del,
确定长度用len
contacts={"小明":"18",
"小黄":"19"}
contacts["小乐"]="21" #添加
contacts["小雪"]="22"
contacts["小汪"]="23"
contacts["小天"]="24"
query = input("请输入你想查找的人")
if query in contacts:
print("您查询的"+query+"年龄为"+contacts[query])
else:
print("用户不存在")
print("当前用户名共" + str(len(contacts))) #len输出的是一个整数,需要转换成字符串输出(字符串和整数不可混合输出)
for循环
for 变量名 in 可迭代对象:
#对变量名做的事情(变量名会依次赋值给列表的对象)
所有带缩进的都是这一循环语句体
字典:
用法:
1、把键值都提取出来
Range(初始值,结束值,步长)
例如 for i in range (5,10)
那么i会依次赋值5,6,7,8,9 #没错没有结束值10,步长默认为1
while循环
while 条件A:
行动B
条件A为假的时候 不继续循环。如果不知道循环次数时候可以用while,但是如果知道循环次数,for循环会更方便
求平均值:
num = input("请输入数字(全部输入后输入q结束输入):")
count = 0
sum = 0
while num != "q":
sum=sum+float(num)
count= count+1
num = input("请输入数字(全部输入后输入q结束输入):")
if count==0:
print("0")
else:
result=sum / count
print(result)
格式化字符串
format方法
{}表示替换的位置,0表示是fromat里面第一个参数,1表示是format里面第2个参数。
通过关键词来指代,此时format里的函数内容顺序无所谓
字符串前加一个f,字符串内的内容会直接求值
数字进行格式化:
:.2f表示这个数字保留两位小数
函数
DRY原则:don’t repeat yourself不要重复你自己
def 函数名字(参数):
代码
return
函数里面参数的值只作用于函数,可以通过return返回,但是没有的话某人返回None
调用的时候直接:
函数名字(参数)
引入模块
如何把别人的代码拿过来用
import加入模块函数
使用的时候是模块名.函数名
from 模块名 import 函数名
使用的时候可以直接使用函数名
**from 模块名 import ***
可以使用该模块下所有的函数,但是不推荐使用,引入了两个模块,但是这中间有重复函数的话就会引出矛盾
若是应用第三方模块
需要先下载安装第三方库。在终端输入:
pip install 库的名字
就可以使用import引入
面向对象编程
面向过程的核心,是把要做的事情拆解完成。
面向对象编程。不会聚焦于完成事情第一步,而是研究其在现实生活中的参数
类是对象的模版,对象是类的实例
或者类是图纸,而对象是建好的房子
把性质绑定在一起,更方便看出性质所属对象
类的方法:放在类里的函数
类的属性:放在类里的变量
封装:把内部内容隐藏起来,外部只需要借口直接使用,不需要知道里面的代码
继承:子类和父类,父类的内容,方法可以被子类继承,不需要反复定义
多态:同样的借口,因为对象具体类的不同而有不同的表现。函数如果是通过不同的类而调用,里面的内容也不一样
class NameOfClass:
#定义类的代码
定义对象的属性
构造函数:定义实例对象的属性,必须背命名为—init—
class CuteCat:
def __init__(self,cat_name):
# (里面可以放任意数量的参数,但是第一个参数是被占用的,self表示用于自身)
self.name=cat_name
# 前面加self,表示是对该对象的属性赋值,若是没有的话python只会觉得是给普通变量赋值
#调用是对象名.参数
cat1=CuteCat("Jojo") #类名(),括号里面放入参数,这样这个方法调用init,而self参数是自动的,就会返回一个对象
print(cat1.name)
定义对象的方法
方法表示对象可以做什么事情
def
要写在class里面,也就是要有缩进。表示属于该类
第一个参数被占用是self,对于init属性来说,第一个参数是self是可以让属性绑定到自身上,而方法需要self,可以在方法里面修改类的属性
class CuteCat:
def __init__(self,cat_name,cat_age,cat_color):
# (里面可以放任意数量的参数,但是第一个参数是被占用的,self表示用于自身)
self.name = cat_name
self.age = cat_age
self.color = cat_color
def speak(self):
# 定义类的方法和定义普通函数是一样的
print("喵" * self.age)
# 喵的打印个数为年龄,通过这样的乘法可以实现
def think(self,content):
print(f"小猫{self.name}在思考{content}...")
#调用是对象名.参数
cat1=CuteCat("Jojo",5,"yellow") #类名(),括号里面放入参数,这样这个方法调用init,而self参数是自动的,就会返回一个对象
# CuteCat.speak()
cat1.speak()
# 应该是定义的对象.函数而不是类.函数,类只是一个模版并没有实际东西
cat1.think("几点下班")
class Student:
def __init__(self,name,student_id):
self.name = name
self.student_id = student_id
# 成绩是一个列表,默认成绩都为0就直接这样定义不需要传入参数
self.grades = {"语文":0,"数学":0,"英语":0}
def SetGrades(self,course,grade):
# 如果传入的cours名称是列表里的键
if course in self.grades:
# grade里面课程对应的值更新为传入的参数
self.grades[course] = grade
def print_grades(self):
print(f"学生{self.name}(学号:{self.student_id})的成绩为:")
#循环打印该学生所有成绩
for course in self.grades:
print(f"{course}:{self.grades[course]}分")
Chen = Student("小陈","20241024")
Wei = Student("小微","20231024")
# print(Chen.name)
Wei.SetGrades("数学",95)
print(Wei.student_id,Wei.grades)
Wei.print_grades()
类继承
子类和父类表示从属关系
子类会继承父类的属性和方法
类名后面括号里写父类
若是子类没有构造函数
子类没有定义方法,所以调用的时候都是用的父类的,但是子类有自己的方法会优先使用子类的,若是没有再前往父类找同名
但是若是又想使用子类又想使用父类的构造函数呢?
使用super
在子类的init构造函数里面
super() init会返回当前类的父类的构造函数
A是B,class A(B)
class Employee:
def __init__(self,name,id):
self.name = name
self.id = id
def print_info(self):
print(f"员工姓名:{self.name},id:{self.id}")
class FullTimeEmployee(Employee):
def __init__(self,name,id,monthy_salary):
super().__init__(name,id)#这里面不用写self
self.month_salary=monthy_salary
def caculate_month_pay(self):
return self.month_salary#不要加引号!
class PartTimeEmployee(Employee):
def __init__(self,name,id,daily_salary,work_days):
super().__init__(name,id)#这里面不用写self
self.daily_salary=daily_salary
self.work_days = work_days
def caculate_month_pay(self):
return(self.daily_salary*self.work_days)
zhangsan = FullTimeEmployee("张三","110",6000)
lisi = PartTimeEmployee("李四","111",120,25)
zhangsan.print_info()
lisi.print_info()
print(zhangsan.caculate_month_pay())
print(lisi.caculate_month_pay())
文件路径
使用代码进行文件编辑
根目录为/。所有目录为/
而win系统为C:\这种表示
绝对路径为/开头,路径中的每个路径中间以/分隔
用.表示当前目录一,…为上级目录,详情见图
在pycharm里面点击文件,右键复制路径,可以看到其的绝对路径和相对路径
文件操作
python读文件
打开:默认为r
f = open("user/demo/data.txt","r",encoding="utf-8")
#使用open打开文件,第一个参数是相对路径或绝对路径,第二个参数r为读取模式(只读),w为写入(只写),第三个为编码方式
#读取成功会返回文件
print(f.read())
print(f.read())
#这个时候会保存读到空字符串,因为会记录该文件读到哪个位置,第一次已经读到结尾,所以第二次会读到空
若是找不到文件会报错FileNotFoundError,
文件有一个read函数,可以一次性读取全部内容,以字符串形式返回,因此喜欢txt纯文本
文件特别大的时候不要用read,内存会爆,可以在其后面括号内写数字,表明读取该数字大小字节的内容
print(f.read(10))#从第一个字符读到第十个
print(f.read(10))#从第十一个字符读到第二十个
print(f.readline())#读取一行内
f.close()
通过while搭配readline。循环读取line(每一行)
f = open("user/demo/data.txt","r",encoding="utf-8")
line = f.readline()
while line!="":
print(line)
line = f.readline()
f.close()
通过for搭配readlines。(一次全部读取完成,将每一行都作为一个列表成员,每一行作为字符串组成列表)
f = open("user/demo/data.txt","r",encoding="utf-8")
lines = f.raadlines()
for line in lines:
print(line)
f.close()
最后要f.close关闭,该文件对象就可以释放系统资源,但有时候会忘记写。也可以通过以下方法结束文件。
with open("user/demo/data.txt","r",encoding="utf-8") as f:
lines = f.readline()
for line in lines:
print(line)
写文件
都需要打开文件,之后要关闭文件,所以可用with
with open("./data.txt","w",encoding="utf-8") as f:
f.write("Hello!\n")
f.write("python")
如果想在原来文件上面追加内容则使用参数是**“a”附加模式**,直接在最后一个字符后面增加。
但是无论是“a“、”w“模式打开文件,都不能对打开的文件进行read。
想要同时读写文件则使用**“r+”**
异常处理
某一行报错后后面的所有报错都不会运行。
异常类型:
对列表引用超出元素数目,可能会产生索引错误IndecError
数字除以零时,产生除零错误ZeroDivisionError
打开文件不存在时:产生找不到文件错误FileNotFoundError
若两个字符串做乘法,产生类型错误TypeError
捕捉异常语句
try:
代码(可能会报错的代码)
except ValueError:
代码(发生错误运行的代码)
except ZeroDivisionError:
代码
except:
代码(捕捉到其它错误后运行的代码)
else:
代码(没有任何错误产生的时候运行)
finally:
代码(不管发生错误与否都运行)
程序从上往下运行,若是前面的except就捕捉到对应的错误,那么后面的except都不运行,类似于if else,运行第一个符合条件的分支语句。
测试
虫子bug
assert语句 断言,在其后面跟上我们认为应当正确的逻辑表达式,若是后面的表达式为True则程序继续运行,若是False就会产生AssertionError断言错误,不再运行后面的代码。
unittest最小单元测试安装
不需要额外进行安装,是一个库
通过import unittest 引入
一般会把测试代码和实现代码分开,测试的代码单独放在一个文件里。
因此要在测试文件引入要测试的函数
from 文件名 import 类名/函数名
#要测试的代码,在原文件
def my_adder(x,y):
return x+y
# 测试文件一定要以test开头!
import unittest
from hello import my_adder
# 命名类的时候使用Test开头可以有效提醒程序是测试案例
# 使用unittest的testcase的子类,就可以使用继承unittest.TestCase的各种测试功能
# 在这个类里面可以定义不同的测试用例,每一个测试用例都是类下面的方法
# 定义的所有方法都必须以test_开头。因为unittest库会自动搜索test_开头的方法,并只把其作为测试案例
class TestMyAdder(unittest.TestCase):
def test_positive_with_positive(self):
#使用assert的话如果报错会直接停止继续运行程序,因此使用其内方法assertEquals
#若是第一个参数和第二个参数相等,则测试通过,不相等则不通过
self.assertEqual(my_adder(5,3),8)
def test_negative_with_positive(self):
self.assertEqual(my_adder(-5,3),-2)
#运行unittest:在终端输入python -m unittest
上面的两个点表示通过的测试,若是有一个测试没通过则是F,并告诉用户是哪个文件的哪个方法出错
后三者是前三者的取反。
本质上都可以使用assertTrue来验证,但还是推荐使用更加针对性的方法,其会给出更有针对性的原因。
为了测试类里的方法,不得不一直创建实例
通过TestCase类里的setUp方法
def setUp(self):
在每一个test_方法使用之前,都会运行一次setUp方法,就可以获得那个已创建好的对象去测试
leetcode刷题练习
1、python的代码框架为
def search(self, nums: List[int], target: int) -> int:
def为定义函数,后面的括号里的内容是参数,self是必须有的。后面nums表示是一个int类型的数组定义方法为:list=[“第一”,“第二”]
target是一个int类型的变量。
-> int表示该函数期待返回的变量实例
2、终端输入python后用control+d或者输入exit()退出python编辑页面
3、变量是可以赋给值的标签
也可以说变量指向特定的值。
变量嫁鸡随鸡嫁狗随狗
4、range()
range(start, stop,step),start为开始数,默认为0。stop为结束数字,但取不到stop。step为步长,默认为1,不能取0
5、enumerate(sequence, [start=0]) 函数
用于将一个可遍历的数据对象sequence(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标start,一般用在 for 循环当中。
leetcode:3
6、计数器Counter()
创建一个哈希表,返回一个字典,注意要大写
https://blog.csdn.net/chl183/article/details/106956807
leeetcode:3 哈希表+滑动窗口
7、map(内置函数,列表)
以列表形式返回,后面所有参数经过函数处理后的值