python基础
要点:
1.深浅拷贝
-
浅拷贝:是创建一个新的对象,新对象的内容是原对象的引用。也就是说,新对象和原对象共享内部对象的引用。如果原对象中有可变对象(如列表),那么新对象和原对象中的可变对象都会指向同一个内存地址,修改其中一个对象的可变对象会影响到另一个对象。
-
深拷贝:是创建一个全新的对象,新对象中的内容是原对象的副本。也就是说,新对象和原对象完全独立,互不影响。无论原对象中是否包含可变对象,都会创建新的对象来存储副本。
-
# 浅拷贝 list1 = [1, 2, [3, 4]] list2 = copy.copy(list1) list2[2][0] = 5 print(list1) # 输出: [1, 2, [5, 4]] # 深拷贝 list3 = copy.deepcopy(list1) list3[2][1] = 6 print(list1) # 输出: [1, 2, [5, 4]]
2.python进制转换
# #类型转换
# #十进制转二进制
# print(bin(12))
# #十进制转8进制
# print(oct(12))
# #十进制转十六进制
# print(hex(12))
# #二进制转shi进制
# print(int('0b1100',2))
# #8进制转10进制
# print(int('0o14',8))
# #16进制转十进制
# print(int('0xc',16))
3.可变类型和不可变类型
"""
可变类型:在存储空间中可以直接修改的数据类型
列表、字典、集合
不可变类型:在存储空间中不能修改的数据类型
数值(int/float/bool)、字符串、元组
【可变类型与不可变类型的本质】:
在内存地址不变的情况下,能否改变其中的数据,若能则是可变类型,若不能则是不可变类型
"""
# 可变类型:演示列表
my_list = ['a', 'b']
print('修改之前:', id(my_list), my_list)
my_list.append('c')
print('修改之后:', id(my_list), my_list)
print('=' * 20)
# 不可变类型:演示int
a = 10
print('修改之前:', id(a))
a = 20
print('修改之后:', id(a))
4.组包和拆包
#组包:= 右边有多个数据时,会自动包装为元组赋值给 = 左边的变量
# a = 10,20,30
# print(type(a),a)
#
# #拆包:多个变量 = 容器数据,当变量数量等于容器长度时,容器中的每个元素会按照次序一一赋值给 = 号左边的变量
# # 10,20,30 先组包成元组(10,20,30),在拆包为每个变量赋值
# a,b,c = 10,20,30
# print(a)
# print(b)
# print(c)
#
# #应用1,交换两个数
# a = 10
# b = 20
# a,b = b,a
# print(a,b)
#
# #应用2,函数返回多个值
# def fun():
# #将三个返回值组包作为一个元组返回
# return 1,2,3
# res = fun()
# #用三个变量去接受,是拆包过程
# a,b,c = fun()
#
# #应用3,遍历字典的的时候
# user_dict={'name':'tom','age':'19'}
# for k,v in user_dict.items():
# print(k,v)
#
# for item in user_dict.items():
# #item 将k和v进行组包,元组形式返回
# print(item)
5.引用和垃圾回收机制
# (1)引用计数,引用也是等号赋值的本质
# ```
# name='张大仙'
# name=a
# name=b
# ```
# 内存中3个变量都指向实际开辟的内存地址空间‘张大仙’,这时引用计数为3,当引用计数为0时,内存空间将会被垃圾回收。
#
# (2)标记清除机制,
#
# 两个列表循环引用的时候,如果直接引用被del,只剩间接引用,那么就去不到两个列表的值了,而引用计数并不为0,# 这时内存不够用的时候就会扫描栈区(栈区存放列表名),把通过栈区能够引用到的标记为存活状态,不能引用到的标
# 记为死亡状态,直接清除。
#
# (3)分代回收机制
#
# 新引入的变量需要检查,对符合规定的变量,检查频率依次降低。解决了引用计数扫描效率低下的问题。
一.输入输出控制
1.格式化输出控制的三种方式
# '格式化输出方式'
# '1按位置传值'
# info = 'my name is %s,i am from %s' % ('张大仙', '广东')
# print(info)
# '字典位置形式传值'
# info = 'my name is %(name)s,i am from %(hometown)s' % {'name': '张大仙', 'hometown': '广东'}
# print(info)
# '2 format功能'
# '大括号什么都不写,还是按位置传值'
# info = 'my name is {},i am from {} '.format('张大仙', '广东')
# '按字典方式传值'
# info = 'my name is {name},i am from {hometown} '.format( name= '张大仙', hometown= '广东')
# print(info)
# info = 'my name is {0},i am from {1} '.format('张大仙', '广东')
# print(info)
# 3'f的方式'
# name=input('输入你的名字:')
# hometown=input('你来自哪里:')
# info = f'my name is {name},i am from {hometown}'
# print(info)
2.格式化填充
# 字符串的三引号(''' ''' , """ """)是按原样格式输出
# 字符串的反斜杠\,是转义字符
# '***开始***'
# '0代表位置,*是填充符号,^代表居中,>和<分别代表左填充和右填充,10代表一共长度'
# a = '{0:*^10}'.format('开始')
# a = '{name:*^10}'.format(name='张大仙',hometown='广东')
# print(a)
3.保留小数三种方式
# num = 1.22334577901
# # 保留两位小数
# print('{0:.2f}'.format(num))
# print('%.2f' % num)
# print(round(num, 2))
二.程序控制结构(判断和循环)
1.判断
-
if 条件1: # if里面代码 # if里面代码 elif 条件2: # 代码 # 代码 elif 条件3: # 代码 # 代码 else: # else里面的代码 # else里面的代码
2.循环
-
while循环
# use_name = 'qwert' # use_pwd = '12345' # count = 0 # while count < 3: # use_name = input('请输入账号:') # use_pwd = input('亲输入密码:') # if use_name == 'Q': # break # if use_name == 'qwert' and use_pwd == '12345': # print('登录成功!') # while True: # action=input('请输入要就行的操作') # if action=='P': # break # print(f'我想要{action}') # break # else: # print('账号密码错误,请从新输入:') # count += 1 # else: # print('输入错误超过三次,账号被锁定!')
-
for循环
# 九九乘法表 # for i in range(1, 10): # for j in range(1, i + 1): # print(f'{j}*{i}={i * j}', end='\t') # print('')
三.容器数据类型
1.list(列表)
1.列表的基本操作
# '列表' '索引对应值'
# '解决了字符串里不能单独修改值的问题'
# '列表里嵌套多个链表'
# person = [['张大仙',73,100,['可乐','厕所','烫头']],
# ['韩信',84,200,['打仗']],
# ['李白',95,0.5,['喝酒','写诗','练剑']]
# ]
# print(person[1][2])
# print(person[2][3][2])
2.列表的增删改查
# #列表的增删改查系列
# l=['q','w','e']
# #列表修改,
# l[0]='t'
# print(l)
# #列表增加,只能在列表末尾增加
# l.append('u')
# print(l)
# #列表插入,按索引插入
# l.insert(0,'p')
# print(l)
# #列表拼接
# l2=['1','2','3']
# #直接+,是创建了新列表,
# print(l+l2)
# #extend方法是在原来的列表基础上增加
# l.extend(l2)
# print(l)
# #列表的删除三种方法
# #第一种del
# del l2[0]
# print(l2)
# #第二种 pop,不传值的时候,默认删除最后一个值,与第一个的区别就是pop会返回删除的值
# ret=l.pop(0)
# print(ret)
# print(l)
# #第三种 remove,按元素来删除值
# l2.remove('3')
# print(l2)
# #查找
#in和not in 判断数据是否在列表里
# l=['q','w','e','r']
# if 'w' in l:
# print('存在')
# if 't' not in l:
# print('不存在')
#count 统计列表中出现的次数
# print(l.count('q'))
# #index 查找值的索引 默认从左往右找,找不到报错,返回下标
# print(l.index('w'))
3.列表的应用
# #列表排序 sort 升序
# num=[2,476,65,3,78]
# num.sort()
# print(num)
# # 逆序 reverse
# num.sort(reverse=True)
# print(num)
#列表的切片 和字符串切片一样,列表切片也是浅拷贝之前值
# l=['q','w','e','r']
# print(l[0:3:2])
#列表的循环 不能将列表的循环和增删放在一起用,这样就会死循环。
# for i in l:
# l.append(i)
# print(l)
# #其它方法
# #clear 清空
# print(l.clear())
# #reverse 翻转 切片是从新复制一个列表,reverse是在原列表修改
# l1=['q','w','e','r']
# print(l1[::-1])
# info=[1,2,3]
# res=info.reverse()
# print(res) # 此时返回为none,因为reverse是在原列表上翻转
# print(info) # 想要输出翻转的结果,输出原来的列表info
# #列表推导式(按条件生成列表,类型转换--字符串转列表)
# data=[x for x in range(1,11)]
# print(data)
# data = [x for x in range(1, 101) if x % 2 == 0]
# print(data)
# data = [x for x in 'hello']
# num =[]
# for i in range(1,4):
# for j in range(1,4):
# num.append((i,j))
# print(num)
# data1=[(a,b) for a in range(1,4) for b in range(1,3)]
# print(data1)
#去除列表重复元素的三种方法
#set方法
# set集合类型: 集合中的数据不可重复,去除列表中的重复数据
# nums = [1, 1, 1, 1, 2, 2, 2, 2, 2]
# nums = list(set(nums))
# print(nums)
#第二种,复制到第二个列表
# nums = [1, 1, 2, 1, 1, 3, 2, 1, 3]
# num1 = []
# for i in nums:
# if i not in num1:
# num1.append(i)
# print(num1)
#在原列表删除
# nums = [1, 1, 2, 1, 1, 3, 2, 1, 3]
# for i in nums[:]:
# while nums.count(i) > 1:
# nums.remove(i)
# print(nums)
2.tuple(元组)
#定义是():name_tuple = ('smart', 'yoyo', 'rock', 'lily')
#查询时和列表一样下标是中括号:print(name_tuple[2])
#元组只能查询,不能增删改
#当元组内只有一个元素时,必须加一个逗号,否则不会被认为是元组:my_tuple=(10,)
# 元组,元素不能改变,只涉及到查数据
# if 'smart' in tuple:
# print('存在')
# #返回特定值的下标
# print(tuple.index(5))
# #返回某个值的个数
# print(tuple.count(3))
3.dict(字典)
# # 字典 列表可以存多个值,但对每个值没有描述,不能一一对应。字典解决这种问题
# info = {'name': '张大仙', 'age': '18', 'tel': '110'}
# # 增
# info['gender'] = '男'
# print(info)
# # 删(del 和 pop)
# del info['gender']
# print(info)
# my_dict.pop('gender')
# print(info)
# # 改
# info['age'] = '100'
# print(info)
# # 查
# print(info['name'])
# #取值
# info.get('name')
# 没有的时候返回None
# # 获取所有的key值
# for i in info.keys():
# print(i)
# # 获取所有的values
# for i in info.values():
# print(i)
# # 获取所有的键值对
# for x, y in info.items():
# print(x, y)
4.str(字符串)
1.字符串基本操作
# 字符串基本操作 由于字符串是不可变类型,方法调用不会修改原字符串内容
# .find(找的第一个)
# .rfind(找的最后一个)
# 'find',查找,,,找不到返回-1
# my_str = 'hello world and itcast and itheima and python'
# ret=my_str.find('and',15,40)
# print(ret) #返回的是第一个字符的下标
# #'index',,,,找不到报错
# ret2=my_str.index('and1')
# print(ret2)
# 'replace'默认全部替换,可以控制替换个数。
# my_str = 'hello world and itcast and itheima and python'
# ret = my_str.replace('and','or',2)
# print(ret)
# split 分割 以列表方式返回 可以指定个数
# my_str = 'hello world and itcast and itheima and python'
# ret=my_str.split('and',2)
# print(ret)
# 字符串拼接
#第一种+号直接拼接
# data1 = '555555@qq.com'
# data2 = '163'
# ret = data1[0:7] + data2 + data1[9:]
# print(ret)
#第二种 join可以将列表里的字符窜进行拼接,可以选择用什么符号
# l=['李白','杜甫','白居易','陶渊明']
# res='-'.join(l)
# print(res)
2.字符串切片
# 切片(范围是左闭右开)
# 下标为-1时,是倒数第一个,指的就是下标
# 0 1 2 3 4 5 6 7
# a b c d e f g h
# 8 7 6 5 4 3 2 1 (-)
# print(data[0:-1])
# data='abcdefgh'
# 取a~e
# print(data[0:5])
# #全输出
# print(data[0:])
# #超过全输出
# print(data[:20])
# #不标注也是全输出
# print(data[:])
# 步长2,间隔一个取,正的向右,负的向左,找不到为空,
# print(data[0:6:2])
# print(data[-6:6:-1]) #此时为空
# 字符串逆制
# print(data[::-1])
5.set(集合)
#集合的重要特点是元素唯一,常和列表字典等结合用于去重
#name_list = ['smart', 'rock', 'yoyo', 'smart']
#my_set2 = set(name_list)
#print(my_set2)
#集合也是大括号:name_list = {'smart', 'rock', 'yoyo'}
#但空集合定义的时候是=set(),不是={},={}是空字典
#集合内的元素没有顺序,不能根据下标取值
#集合的符号运算
# hobbies1={'吃饭','睡觉','健身','游泳'}
# hobbies2={'吃饭','睡觉','打游戏','看剧'}
# #取交集
# print(hobbies1 & hobbies2)
# hobbies1.intersection(hobbies2)
# #取并集
# print(hobbies1 | hobbies2)
# hobbies1.union(hobbies2)
# #取差集(个人独有的爱好)
# print(hobbies1 - hobbies2)
# print(hobbies2 - hobbies1)
# hobbies1.difference(hobbies2)
# #对称差集(两个人独有的差集)
# hobbies1.symmetric_difference(hobbies2)
# print(hobbies1 ^ hobbies2)
# #父子集(包含关系)
# #父集
# hobbies1.issuperset(hobbies2)
# #子集
# hobbies1.issubset(hobbies2)
6.共有方法,函数
函数:
-
len(容器):求长度
-
max(容器):求最大
-
min(容器):求最小
-
sum(容器):求和
-
enumerate(容器):配合for对容器进行遍历,同时获取元素和下标
my_list = [1, 3, 2, 5, 8, 7] for i,num in enumerate(my_list): print(i,num) 0 1 1 3 2 2 3 5 4 8 5 7
切片:
- 字符串、列表、元组
运算符:
-
-
new_list = [1, 2] + [3, 4] print(type(new_list), new_list) new_list = [1, 2] * 2 print(type(new_list), new_list) new_str = 'hello' * 2 print(type(new_str), new_str) <class 'list'> [1, 2, 3, 4] <class 'list'> [1, 2, 1, 2] <class 'str'> hellohello
-
in、not in
- 对于字典来说,是判断字典中是否存在某个键
-
==
判断是否相等
四.函数
1.函数定义,嵌套
# def func(a, b, c):
# """
# 计算三个数的和,并求平均值
# :param a:
# :param b:
# :param c:
# :return:
# """
# sum = a + b + c
# ret = sum / 3
# return sum,ret
#
# a = func(3, 6, 9)
# print(a)
--------------------------------------------------
# 函数嵌套 函数没有返回值的时候,打印的都是None
# def fune1(a, b):
# print(a)
# print(b)
# return a + b
#
# def fune2(x, y):
# print('q')
# c = fune1(x, y)
# return c
#
# print(fune2(10, 20))
2.函数作用域
#变量的作用域
#函数内--局部变量
#函数外---全局变量
#如果有全局变量和局部变量,就近原则
#如果想在函数内部修改全局变量,要进行global声明
# num =10
# def fune():
# global num
# num = 20
# print('函数内',num)
# fune()
# print('函数外',num)
-----------------------------------------------------------
# 函数返回多个返回值
# def fune():
# a = 10
# b = 20
# # 返回多个值
# return a, b
#
# # 多个返回值时,默认返回元组。
# print(fune())
# # 可以用两个变量来接受返回的两个值
# num1, num2 = fune()
# print(num1)
# print(num2)
-------------------------------------------------------------
# import random
# #num是全局变量,但列表是特殊的可以不用声明
# num=[]
# def fune1():
# #最好声明
# global num
# num.append(random.randint(1,10))
# return num
# def fune2():
# a=int(input('输入要产生的个数:'))
# for i in range(a):
# fune1()
# return num
# print(fune2())
3.函数参数
#实参分类:
#1.位置参数-----形参和实参一一对应
#2.关键字参数,可以不用一一对应,用键值对传参,关键字参数必须写到位置参数后面
# def use_info(name,age,gender):
# print(f'您的名字是:{name},年龄是:{age},性别是:{gender}')
# use_info('tom',gender='男',age=18)
#当参数只有一个时,默认传给第一个,这时需要关键字参数和缺省参数一起使用解决
# def use_info(name='',age='',gender=''):
# print(f'您的名字是:{name},年龄是:{age},性别是:{gender}')
# use_info(gender='女')
#形参分类:
#1.普通形参:调用时必须传实参
# def func(a,b):
# return a+b
# func(1,2)
#2.缺省参数:解决参数传少了,可以有默认值,即使参数传不够,也不会报错
# def use_info(name,age='18',gender=''):
# print(f'您的名字是:{name},年龄是:{age},性别是:{gender}')
# use_info('tom',gender='男')
#3.不定长参数: *args:以元组的方式,获取多余的单值参数,**kwargs:以字典的形式获取多余的键值对形式的参数
# def info(a,*args,**kwargs):
# return a
#
# print(info(10, 3, 34, name='tom', age=18))
#注意:函数定义时多种类型形参需要注意次序
#普通形参 > 元组不定长形参 > 缺省形参 > 字典不定长形参
-----------------------------------------------------------
"""函数作为参数,进行调用"""
# def application(func):
# a = 10
# b = 20
# func(a, b)
#
# def func1(num1, num2):
# print(num1 + num2)
#
# def fune2(num1, num2):
# print(num1 - num2)
# application(func1)
# application(fune2)
-------------------------------
# 匿名函数作为参数
# def fune(fan,n1,n2):
# res=fan(n1,n2)
# print(res)
#
# fune(lambda a,b:a*b,1,2)
4.函数定义lambda 用法(匿名函数)
# 函数定义lambda 用法 函数名=lambda 参数 : 表达式
#注意:
#1)匿名函数中不能使用 while 循环、for 循环,只能编写单行的代码
#2)匿名函数中返回结果不需要使用 return,单行代码的结果就是返回值
# func3 = lambda: print('123')
# func3()
#
# func4 = lambda a, b: print(a + b)
# func4(10, 20)
#
# #a*b不需要用return来返回,自动返回
# func5 = lambda a, b: a * b
# ret = func5(2, 5)
# print(ret)
# 匿名函数
# def application(func):
# a = 10
# b = 20
# func(a,b)
#
# application(lambda a,b:print(a+b))
# application(lambda a,b:print(a-b))
五.文件
1.文件基本操作
# 文件 三个操作
# r 是读文件,
# f = open('C:\pyc\PycharmProjects\lianxi\data.txt','r',encoding='utf8')
# 全部读出
# file_data=f.read()
# 按行读出
# file_data1=f.readline()
# 所有行都读出,并用列表表示
# file_data12=f.readlines()
# f.close()
# print(file_data)
# w 是覆盖原来的写入,写入的文件不存在,就会自动创建,并写入
# f = open('./data.txt','w',encoding='utf8')
# f.write('ha ha ha\n')
# f.write('he he he')
# f.close()
# # a 追加写入 ,没有文件直接创建
# f = open('./data.txt','a',encoding='utf8')
# f.write('\nha ha ha\n')
# f.close()
# 文件默认是字符串类型,想要转化为原来类型,需要eval()函数进行转化
# f = open('./data1.txt', 'r', encoding='utf8')
# file_data = f.read()
# file_data = eval(file_data)
# print(file_data[0])
# print(file_data[1])
# print(file_data[2])
#
# f.close()
# rb 二进制格式的只读操作。
# wb 二进制格式的只写操作。
# ab 二进制格式的追加操作。
2.文件操作应用
# 判断文件中是否有字母,函数调用。
# def func(data):
# f = open('C:\pyc\PycharmProjects\lianxi\data.txt', 'r', encoding='utf8')
# file_data = f.readlines()
# f.close()
# num = 1
# for i in file_data:
# if data in i:
# print(f'{num}行有{data}这个数据')
# num += 1
#
#
# func('h')
# 实现复制粘贴功能(如果要实现图片等备份,要用rb,wb,二进制的方式进行)
# file_name = input('请输入要复制的文件名:')
# c = '[复制]'
# ret = file_name.find('.')
# print(ret)
# new_name = file_name[:ret] + c + file_name[ret:]
# print(new_name)
#
# f = open('./data.txt','rb')
# file_name_data=f.read()
# print(file_name_data)
# f.close()
#
# f = open('./data复制.txt','wb')
# f.write(file_name_data)
# f.close()
#批量修改文件名
# import os
#
# os.chdir('./my_test')
# file_name_list = os.listdir()
# for i in file_name_list:
# new_name =i[:i.find('.')] + '[大哥专享]' + i[i.find('.'):]
# os.rename(i,new_name)
#统计文件字符数 (生成器表达式)
with open('student.txt','rt',encoding='utf-8')as f:
size=sum(len(line) for line in f)
print(size)
六.os模块
# os模块
# import os
# #切换目录
# os.chdir('../')
# # 获取当前目录
# print(os.getcwd())
# 把当前所有文件信息显示出来,并存到一个列表里
# print(os.listdir())
# #重命名
# os.rename('data2.txt','data4.txt')
#批量修改
import os
# # os.mkdir('py')
# # os.chdir('py')
# for i in range(1,6):
# f = open(f'python基础班-{i}.txt','w',encoding='utf8')
# f.close()
#
# file_name_list=os.listdir()
# for file_name in file_name_list:
# new_name='[黑马]'+file_name
# os.rename(file_name,new_name)
七.异常捕获
# #异常捕获,避免因为程序中的一个bug而使整个程序不能运行
# print('start')
# try:
# num=int(input('请输入:'))
# a=10/num
# except Exception as e: #(Exception 可以捕获大部分异常)
# print('发生异常!',e)