碎碎念:发现越到后面越显得基础的重要了,比如说有时候发现跟同学问的列表有关的操作,定义列表list1 =list[]删除元素list1.del()和list.remove()的区别竟然都不知道了。del是按照数组元素下标巧记l下标进行删除,remove是根据元素的值进行删除,真的是基础不牢地动山摇啊!最后再补充一些使用的Python的函数使用方法和小技巧吧。

Python中的输入和输出(※)

第一种输出方式:

1
2
3
4
name = "老李"
age = 18
height = 18.2
print("我的名字是:%s,年龄是:%d,身高是:%.3f" % (name , age , height))

第二种输出方式:

1
print(f'名字是{name},年龄是{age},性别是{gender}')

输入方式:

1
2
3
4
price = float(input("请输入苹果单价:"))
weight = float(input("请输入购买的重量"))
money = price * weight
print("总共的钱是:%.2f" % money)

判断语句和循环语句

if语句:

  • 和java有比较大的区别,java在写if语句时候后面要跟上()括号

if语句是用来进行判断的,其使用格式如下:

1
2
if 要判断的条件:
条件成立时,要做的事情

注意点:

1
2
3
>>> # not:将右边表达式的逻辑结果取反,Ture变为False,False变为True
... if not (1 == 2):
... print("条件成立!")

if,elif语句:

使用格式如下:

1
2
3
4
5
6
7
8
if xxx1:
事情1
elif xxx2:
事情2
elif xxx3:
事情3
else:
事情4

if的嵌套:

1
2
3
4
5
6
7
8
9
10
ticket = 1
knief_length = 1
if knief_length <= 7:
print("可以过安检")
if ticket == 1:
print("可以上车乘车")
else:
print("不能上车")
else:
print("No")

随机数的生成方式:(※)

  • 第一步:导入随机数: import random
  • 第二步:生成随机数:computer = random.randint(0,2)

注意:randit(0,2) 生成的随机数为0,1,2三个

注意:range和字符串切片都是左闭右开区间,取左不取右

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import random   #导入随机数

while True:
num = input("请输入:石头(0),剪刀(1),布(2):")
num = int(num)
computer = random.randint(0,2) #从0,2中随机生成一个数字
if num == computer:
print("平局")
elif (num == 0 & computer == 1 ) or (num == 1 & computer == 2 ) or (num == 2 & computer == 0 ):
#举例列举出玩家赢的情况
print("恭喜你获胜")
break
else :
print("决战到天亮")

while循环

举例:(求1-100累加和)

1
2
3
4
5
6
i = 0
sum = 0
while i <= 100:
sum += i
i += 1
print(sum)

for,else(※)

以前只听说过if,else,没想到还有for,else。所以是个注意点,要不然看不懂代码;

for后面跟else,else只有在循环正常结束时才会执行

1
2
3
4
5
6
7
for i in '1234567':
if i == '4':
print("有不吉利的数字")
break
else:
#else只有在循环正常结束时才会执行
print("没有不吉利的数字")

break和continue

break的作用:

  • 立刻结束break所在的循环

continue的作用:

  • 用来结束本次循环,紧接着执行下一次的循环
1
2
3
4
5
for i in "1234567":
if i == 4:
print("有不吉利的数字")
break
print(i)

for循环(嵌套)(range和切片※)

1
2
3
4
for i in range(5):    #外层循环
for j in range(5): #内层循环
print("*",end=" ")
print()

容器

容器包括:字符串、列表、元组、字典

字符串

类似于:data = ‘abcdefg’

下标和切片(注意和range一样左闭右开)

1
2
3
4
5
6
7
8
9
data = 'abcdefg'

print(data[0:6]) #基本用法(取到下标0-5的字符)
print(data[1:-2]) #负数的下标(取到bcde,因为g是-1,f是-2,而且取不到-2所以是e)
print(data[:]) #不写下标(全取完)
print(data[0:5:-1]) #步长正负的使用(步长为负数,从右往左数,取不到东西,0下标往左数没东西了)
print(data[0:5:2]) #步长长度的使用(取到ace)
print(data[::-1]) #特殊用法(将字符串逆置)
print(data[5:1:2]) #取不到东西,因为从5到1只有步长为负数才行

字符串的常见操作

查找元素下标:(index,find都是返回元素下标的函数)

  • 字符串序列.find(子串, 开始位置下标, 结束位置下标)
  • 字符串序列.index(子串, 开始位置下标, 结束位置下标)

修改–replace(),split()

  • 字符串序列.replace(旧子串, 新子串, 替换次数)
  • 字符串序列.split(分割字符, num)
1
2
3
4
5
6
7
8
9
10
mystr = "hello world and itcast and itheima and Python"
ret = mystr.find("and", 20, len(mystr)) #find函数
tmp = mystr.index("and", 0, len(mystr)) #index函数
#index函数和find函数
print(ret)
print(tmp)
a = mystr.replace("and"," ",2) #replace函数
print(a)
b = mystr.split("and",3) #split函数
print(b)

字符串另外的20多种操作这里就不一一介绍了;

列表(※)

列表操作之增删改查(curd)

  • 添加元素:append, extend, insert

  • 修改元素:修改元素的时候,要通过下标来确定要修改的是哪个元素,然后才能进行修改

  • 查找元素: in, not in, index, count

    • >>> a = ['a', 'b', 'c', 'a', 'b']
      
      >>> a.index('a', 1, 4)
      3
      >>> a.count('b')
      2
      
      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

      - `删除元素: del, pop, remove`※

      - del是按照下标进行删除
      - remove是按照元素的值进行删除

      ```python
      my_list = [1, 12, 3, ['老李','老张']] # 列表里面还可定义列表
      print(my_list[3][1]) # '老李'
      print(my_list[2]) # '3'
      print(my_list.index(3, 0, 4)) # '2',查找元素3的下标,在0到4区间查找
      print(my_list.count(1)) # 统计元素1出现的个数
      my_list.append("张阿四") #append()在列表的末尾追加数据
      print(my_list)
      names = ["xiaofei","zhangsan"]
      names.append(my_list)
      print(names)
      names.extend(my_list) # 通过extend可以将另一个集合中的元素逐一添加到列表中
      print(names)
      my_list.insert(1,"老六") # 在下标1位置插入元素
      print(my_list)

      # 修改元素
      my_list[1] = 'xiaoLu'

      # 查找元素
      name_list = ['xiaoWang','xiaoZhang','xiaoHua']
      find_name = input('请输入要查找的姓名:')
      #查找是否存在
      if find_name in name_list:
      print('在列表中找到了相同的名字')
      else:
      print('没有找到')


列表和循环搭配容易踩的坑

由于忽略列表遍历是按照下标进行遍历的:

1
2
3
4
5
a = [1, 1, 3, 1, 1, 3, 2, 4]
for i in a:
if a.count(i) > 1:
a.remove(i)
print(a)

正确的方法:

1
2
3
4
5
6
7
a = [1, 1, 3, 1, 1, 3, 2, 4]
# for循环按照元素下标取元素
for i in a[:]: #对a取切片,就生成了一个新的列表,但是这个列表和a中的元素是一样的
if a.count(i) > 1:
a.remove(i)

print(a)

列表推导式

作用:用一个表达式创建一个有规律的列表或控制一个有规律列表。

列表推导式又叫列表生成式。

1
2
3
4
5
a = [x for x in range(10) if x % 2 == 0]
print(a) # [0, 2, 4, 6, 8]

b = [(x,y)for x in range(0,3) for y in range(0,2)]
print(b) # [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]

Python中的去重,排序,逆置元素,交换元素(※)

去重对比

1
2
3
4
5
6
7
8
9
10
11
12
# 一般的去重方式
a = [1, 2, 2, 1, 2, 1, 3]
b = []
for i in a:
if i not in b:
b.append(i)
print(b)

# Python中的去重方式
a = [1, 2, 2, 1, 2, 1, 2]
a = list(set(a))
print(a)

排序对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 一般的冒泡排序
alist = [3, 5, 9, 2, 1, 7, 8, 6, 4]

def bubble_sort():
for j in range(len(alist)-1): #重复下面的操作n-1次即可将n个数据排完序
for i in range(len(alist)-1): #这里的三句可看成一个整体,将一个最大的9移动到了最右边
if alist[i] > alist[i+1]:
alist[i],alist[i+1] = alist[i+1],alist[i] #Python中交换两个变量
print(alist)

bubble_sort()

# Python中的排序
a = [1, 10, 9, 2, 5]
a.sort(reverse=False)
print(a)

Python逆置元素

1
2
3
4
# Python中的逆置
a = [1, 2, 3, 4]
a.sort(reverse=True)
print(a)

Python交换元素和其他语言交换元素(a, b = b, a 交换a,b的值)

其他语言:

1
2
3
4
5
6
7
8
9
# 方法一(左差法)
a = 100
b = 200
a = a + b
b = a - b
a = a - b
print(a,b)

# 方法二(使用临时变量temp)

python:

1
2
3
4
a = 100
b = 200
a,b = b, a
print(a,b)

元组

元组的特性

  • 一个元组可以存储多个数据,元组内的数据是不能修改的

元组的操作(只有查index,+,count)

1
2
3
4
5
6
7
8
9
10
11
12
tuple1 = ('af', 'dd', 'ee', 'dd')
tuple2 = ('11', '22', '33', '44')
result = tuple1 +tuple2
print(result) # ('af', 'dd', 'ee', 'dd', '11', '22', '33', '44')
print(len(tuple2)) # 4
print(max(tuple2)) # 44
print('11' in tuple2) # True


print(tuple1.index('dd')) #打印下标
print(tuple1[0]) #根据下标打印元素
print(tuple1.count('dd')) #统计元素出现的次数

元组装包和拆包

元组装包: 个人理解,就是定义元组的时候,不用写小括号

元组拆包: 用字符接收元组的值时候,直接写a,b = tuple这种就是自动拆包

1
2
3
4
5
6
7
8
9
# 自动装包
my_tuple = 1,2
print(type(my_tuple)) #<class 'tuple'>
print(my_tuple)

#自动拆包
a,b = my_tuple
print(a)#1
print(b)#2

字典

字典存储的是键值对。

使用get获取字典中的元素

get() 方法 和dict[key] 访问元素区别

  • get(key) 方法在 key(键)不在字典中时,可以返回默认值 None 或者设置的默认值。

  • dict[key] 在 key(键)不在字典中时,会触发 KeyError 异常

1
2
3
info = {'name':'吴彦祖','age':18}
sex = info.get('sex')
print(sex)

直接通过键来查看值

1
print(info['age']) # 获取年龄

字典操作之curd

1
2
3
4
5
6
7
my_dict = {'name':'小明', 'age':'18', 'gender':'男'}
my_dict['sex'] = '男' #增加
del my_dict['sex'] #删除
my_dict['gender'] = '女' #修改
print(my_dict['name']) #查看
print(my_dict)
my_dict.clear # 清空字典

keys()

显示所有的key值

1
2
3
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
print(dict1.keys())
>>>dict_keys(['name', 'age', 'gender'])

values()

显示所有的value值

1
2
3
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
print(dict1.values())
>>>dict_values(['Tom', 20, '男'])

items()

显示所有的键值对(key-value形式)

1
2
3
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
print(dict1.items())
>>>dict_items([('name', 'Tom'), ('age', 20), ('gender', '男')])

集合

如何定义集合: 形如my_set = {}和字典定义的符合相同,不过字典存储的是键值对

集合的特性: 集合不能存储重复的元素

增(add函数)

1
my_set.add(4)#{1, 2, 3, 4}

删除(pop, remove函数)

1
2
my_set.pop() #从头部删除
my_set.remove(4)# 指定删除

函数

  • 函数有多个返回值的时候,会将返回值以元组的形式返回
1
2
3
4
5
6
7
8
def func():
return 100, 200


ret = func() #函数有多个返回值的时候,会将返回值以元组的形式返回
print(ret)
a,b = func()
print("%d, %d" % (a, b))

函数的参数

  • 形参:函数定义时小括号中的参数,用来接收参数用的,称为 “形参”
  • 实参:函数调用时小括号中的参数,用来传递给函数用的,称为 “实参”

参数的类型

  • 位置参数: 根据函数定义的参数位置来传递参数
1
2
3
4
5
def user_info(name, age, gender):
print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}')


user_info('TOM', 20, '男')
  • 关键字参数:函数调用,通过“键=值”形式加以指定。
1
2
3
4
5
6
def usr_info(name, age, gender):
print(f'名字是{name},年龄是{age},性别是{gender}')


usr_info('老王', age=18, gender='女')
usr_info(name='老李', gender='男', age=12)
  • 缺省参数:在函数定义时为形参提供默认值

比如:

def usr_info(name, age='未知', gender='未知'):

  • 不定长参数:不确定调用的时候会传递多少个参数
  • 作用(参数传多了的问题)* args将多余的参数以元组的形式存储起来 ,**kwargs用于存储多余的键值对
1
2
3
4
5
def usr_info(name, age, gender ,*args, **kwargs):
print(f'名字是{name},年龄是{age},性别是{gender}')
print(args) #args负责将多余的普通参数以元组的形式存储起来
print(kwargs) #kwargs负责将多余的键值对以字典的形式存储起来
usr_info(1,2,3,4,5,sex='女',height='187cm') #注意应该将普通参数放在键值对参数的前面

函数作为参数

函数作为一个参数,函数名存储的是函数内存空间的地址

下面这个例子:在函数调用时func==my_add

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 函数作为一个参数,函数名存储的是函数内存空间的地址
def application(func): #先调用application再将func==my_add
a = 100
b = 200
sum = func(a, b) #执行到此句开始调用my_add函数
print(sum)


def my_add(num1, num2): #将a,b实参传递并计算结果返回
ret = num1 + num2
return ret


application(my_add) # 将函数作为一个参数传递给application,

匿名函数

使用lambda创建小型的函数,省去了用def创建函数的步骤

lambda函数也叫匿名函数

1
2
3
4
5
6
7
8
func = lambda a, b : a - b      #冒号后面的相当于是返回值

def application(func):
ret = func(100, 200)
print(ret)


application(func)
1
2
3
4
5
6
7
8
def application(func):
a = 100
b = 200
ret = func(a, b)
print(ret)


application(lambda a, b: a + b)

匿名函数和sort排序结合

1
2
3
4
5
6
7
# 使用lambda表达式进行列表的排序
# todo : sort 函数排序如果遇到不能排序的数据类型,会直接调用Key函数处理,此时遍历的元素就是传递给key函数的参数

list1 = [{"name": 'jerry', "age": 20},{"name": 'tom', "age": 19},{"name": 'rose', "age": 22}]
# 解释: 排序会遍历整个列表的元素, 但是由于给了key值
list1.sort(key=lambda dict_stu: dict_stu.get("age"))
print(list1)

闭包

闭包的构成条件

  • 在函数嵌套(函数里面在定义函数)的前提下

  • 内部函数使用了外部函数的变量(还包括外部函数的参数)

  • 外部函数返回了内部函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def func_out(func):     #第二步
def func_in():
print('验证')
func() #此时func() == log_in()

return func_in #第三步


def log_in():
print("登陆")


log_in = func_out(log_in) # 第一步 调用函数func_out并将log_in函数作为参数传递(得log_in=func_in)
log_in() #第四步,log_in == func_in故log_in()== func_in(),先打印验证后打印登陆

装饰器

装饰器的功能:就是给已有函数添加新的功能

  • 不修改已有函数的1源代码
  • 不修改已有函数的调用方式
  • 给函数添加功能

装饰器是特殊的闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def func_out(func):     #第二步
def func_in():
print('验证')
func() #此时func() == log_in()

return func_in #第三步


@func_out #装饰器——等价于log_in= func_out(log_in)
def log_in():
print("登陆")


log_in()

文件操作

普通文件操作

1
2
3
4
5
6
7
8
9
10
11
12
13
f = open("./test.json", 'a', encoding="utf8")  # 参数(路径和文件打开方式和解码方式)
# 路径:.代表当前路径,..代表上一级路径,还可以写成绝对路径如C/User/Stray
# 文件打开方式r(只读) W(覆盖写)a(追加写)->append
# 编码格式(utf8,gbk等)
data = f.write('wocao')
f.close()

# 这种文件打开方式的好处是不用自己关闭文件,进程结束文件就自己关闭了,少写了f.close()
with open("test.json", 'r', encoding="utf8") as f:
ret = f.read() # read是有参数的,并且以字节为单位,不写参数默认有多少读取多少
print(ret)
f.readline(5) # readline默认读取一行,文件读取的时候如果不关闭文件,则会记录读取上一次读取的位置
f.readlines() # 一次读取所有行,并把数据存储到列表中

文件的复制(并重新命名)

1
2
3
4
5
6
7
8
# 需求:文件的写操作(需求,创建一个文件的复制文件并以-文件复制.json-重新命名)
name = "test.json"
new_name = name[:4] + '复制' + name[4:] #name[:4]为test
with open('test.json', 'r') as f:
new_content = f.read()
f.close()
f = open(f'{new_name}', 'w')
f.write(new_content)

普通txt文件复制改进

了解改进的前提: 知道文件读取是放入到内存中的, 如果内存(缓冲区满了)文件还没有写入到磁盘中,就会导致内存溢出.所以要及时刷新缓冲区,及时写入到内存中.

  • 改进的一点就是,如果文件太大,要用flush刷新缓冲区.
  • 第二点是readline和readlines的区别,readline是一次读取一行,要把文件读取完需要结合while循环一起使用
  • readlines是一次读取完文件,文件太大可能导致内存溢出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 文本文件的复制
file = open(r"\\Mac\Home\Desktop\a.txt", 'r', encoding='utf8')
file_need_write = open("a.txt", "w", encoding="utf8")
count = 0
while True:
# 一次读取一行(保证内存不会溢出
data = file.readline()
# 将读取到的数据写入到待写入文件中
file_need_write.write(data)
# 每写入一次count就加一,保证在1000次的时候刷新缓冲区
count += 1
if count % 1000 == 0:
# 在读取1000次的时候刷新缓冲区
file_need_write.flush()
# if len(data) == 0:
# break
# 判断读取到数据为空更优雅的写法(if data 表示data不为空就执行break,但是我们希望为空再break所以加not
if not data:
break
# 读取文件关闭
f.close()
# 写入文件关闭
file_need_write.close()

非文本文件的复制(二进制)

和上面文本文件的复制大同小异,不过w要替换成wb,r要替换成rb(二进制文件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 非文本文件的复制
# 打开文件
f = open(r"\\Mac\Home\Desktop\cheat engin使用方法.png", "rb")
f1 = open('b.png', "wb")
count = 0
while True:
# 读取图片,每次读取1024字节
data = f.read(1024)
f1.write(data)
count += 1
if count % 1000 == 0:
f1.flush()
if len(data) == 0:
break
f.close()
f1.close()

关于JSON文件的操作

json.load()和json.loads()的区别:
json.load()方法是从json文件读取json,而json.loads()方法是直接读取json,
两者都是将字符串json转换为字典。

1
2
3
4
5
6
7
8
9
10
11
import  json
a={'value':'000','type':'rgb'}
print(type(a))
a = json.dumps(a) # 将字典类型转换为字符串类型(写入文件中刚好)
print(type(a))
a = json.loads(a) # 将字符串类型转换为字典
print(type(a))
b = a.get('value') # 获取a中value键的值
print(b)
c = a['value']
print(c)

dump[dʌmp]倾倒; 抛弃; 转存
json.dumps()和json.loads()是json格式处理函数(可以这么理解,json是字符串)。
json.dumps()函数是将一个Python数据类型列表(字典)进行json格式的编码(可以这么理解,json.dumps()函数是将字典转化为字符串)。

OS模块

1
2
3
4
5
6
import os

os.rename() # 给文件重新命名
os.getcwd() # 获取当前工作路径
os.chdir() # 修改工作路径
os.listdir() #获取当前路径下的所有文件名称

文件名批量修改脚本

1
2
3
4
5
6
7
8
9
10
import os
os.chdir("./aaa") #修改路径到当前路径下的aaa文件夹
file_list = os.listdir() #获取当前路径下的所有文件名称
print(file_list)

for list_name in file_list: #list_name ==> a.txt
my_index = list_name.find(".") #查找.元素的下标
new_name = list_name[:my_index] + "[俊威出品]" + list_name[my_index:]
# new_name = list_name[:my_index-len("[俊威出品]")] + list_name[my_index:] #修改回来
os.rename(list_name, new_name)

异常

捕获已知类型的异常

1
2
3
4
5
try:
num = int(input("请输入分母:"))
result = 1 / num
except (ZeroDivisionError, NameError): #根据异常的类型进行捕获
print("分母不能为0/其他error")

捕获未知类型的异常(异常完整语法)※

try:(捕获异常)

​ except Exception as e:(异常处理)

else:(没有异常)

finally:(有没有异常都要执行)

1
2
3
4
5
6
7
8
9
10
11
12
13
try:
f = open('aaa.txt', 'r')
except Exception as e:
print("文件打不开,我给你创建一个吧")
with open('aaa.txt', 'w') as f:
f.write('Wocao')
else:
#如果没有异常就执行这里
data = f.read()
print(data)
finally:
#不管有没有异常都要执行finally
f. close()

模块导入

制作模块

在文件夹中new - >Python package,命名为util包在__init__中写_all_=[‘py文件名’]表示对外公开的模块

1
2
3
4
5
6
7
# 导入模块的方式

import 模块名
from 模块名 import 功能名
from 模块名 import *
import 模块名 as 别名
from 模块名 import 功能名 as 别名
1
2
3
4
5
6
7
# import 包名.模块名
import base.base_a
base.base_a.base_a()

# from 包名 import 模块
from util import util_a
util_a.util_a()

小技巧(Tricks)

1
2
3
4
5
6
7
8
9
10
11
快速注释 ==>  Ctrl+l

强制类型转换 ==> b = 12.43 rent = int(b)

type函数 ==> 查看变量类型如type(a)

len函数 ==> 查看变量的长度

在写if __name__ == '__main__':时,写个main然后按Tab

设计学生管理系统,用列表里面嵌套字典的方式存储数据