# 单行注释
"""
多行注释
"""
程序运行时用来接收中间结果,保存在内存中
定义时不像强类型语言那样需要提前声明变量的类型,python会自动解析变量的数据类型
name = "pihao"
age = 18
gender = 'male'
# 查看python中的关键字
import keyword
print(keyword.kwlist)
# python中的关键字如下:
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
下面两种命名方式都是官方推荐,个人更偏向于下划线命名法,看着舒服简洁
# 下划线
my_name = 'pihao'
order_delete_flag = False
# 驼峰
myName = 'pihao'
orderDeleteFlag = True
这个没啥说的,就是使用 “ = ” 赋值呗,其实就是为内存中的值取一个名字,用这个名字指向内存区域中的值。
name1 = 'python'
name2 = name1
name3 = name2
print(name1) #python
print(name2) #python
print(name3) #python
name1 = 'java'
print(name1) #java 将原来指向python的引用断开,重新指向java
print(name2) #python 指向python的引用
print(name3) #python
即不会变化的量。
比如在java中的常量我们使用final来修饰,并且该常量的值如果改变了还会抛出错误,但是在python中没有专门的语法来表示常量,我们就都默认变量名全部大写的为常量
# 定义一个常量
WEBSITE_URL = 'www.baidu.com'
python的数据类型有多种,但先说说说3中基本数据类型;就像java的数据类型也有多种,但是基本数据类型就是8种:byte、short、int、long、float、double、char、boolean
int(整型)
除了int类型外,还有float浮点型,复数型等
在python中,有引号的字符都是字符串,单引号和双引号都行
在python中,单引号和双引号没有区别。
# 这种情况考虑使用单、双引号的组合
msg = "the order's number is error,please check it out"
在python中,多引号怎么使用呢?
# 多行字符串必须使用多引号
msg = '''
七星鲁王宫,
怒海潜沙,
秦岭神树,
云顶天宫...
'''
字符串拼接
字符串的拼接有两种
first_name = 'pi'
last_name = 'hao'
print(first_name+last_name) # pihao
print('python ' * 5) # python python python python python
注意:字符串不能与数字相加,这点与java区分开来
python中布尔类型的值只有两种:True False
程序接收控制台输入的参数
# 将用户输入的密码赋值给password
password = input("请输入登入的密码: ") #请输入登入的密码: 123456
# 使用type()方法打印接收的类型
print(type(password)) #
# 注意:只有是由input()方法接收的参数,它的类型都是字符串str
废话不多说,入门必备
"""
if 条件:
满足条件后要执行的代码
"""
if True:
print('ok')
"""
if 条件:
满足条件执行代码
else:
if条件不满足就走这段
"""
time = '凌晨两点'
if time == '凌晨两点':
print('快睡吧,狗命要紧')
else:
print('扶我起来,我还能学习')
"""
if 条件:
满足条件执行代码
elif 条件:
上面的条件不满足就走这个
elif 条件:
上面的条件不满足就走这个
elif 条件:
上面的条件不满足就走这个
else:
上面所有的条件不满足就走这段
"""
score = 60
if score >= 95:
print("A")
elif score >= 80:
print("B")
elif score >= 60:
print("C")
else:
print("D")
# 这里需要注意一个问题,elif是从上往下执行的,只要满足了某个条件,那么就执行,其他的就不会再往下走了
不多说,与其他语言类似
while 条件:
# 循环体
# 如果条件成立,则执行循环体
# 如果条件不成立,则不执行
# 演示生活中音乐循环播放
while True:
print("遥望")
print("原谅我今天")
print("愿我能")
print("曾是拥有")
print("无悔这一生")
# 求100内所有的和,包括100
index = 1
sum = 0
while index<101:
sum += index
index += 1
print(sum)
# 打印九九乘法表
row = 1
while row <= 9:
col = 1
while col <= row:
print('%d * %d = %d' % (col, row, col * row), end='\t')
col += 1
print('')
row += 1
·
结束循环的方式有多种
改变条件
flag = True
while flag:
print("遥望")
print("原谅我今天")
print("愿我能")
flag = False
print("曾是拥有")
print("无悔这一生")
使用关键字break
使用break关键字,循环中遇到break就会立马退出循环, 类似java,这对java程序员就非常友好了
flag = True
while flag:
print("遥望")
print("原谅我今天")
print("愿我能")
break;
print("曾是拥有")
print("无悔这一生")
continue
continue 用于终止本次循环,继续下一次循环
flag = True
while flag:
print("遥望")
print("原谅我今天")
print("愿我能")
continue;
print("曾是拥有")
print("无悔这一生")
与其他语言不同,else一般只与if搭配,在python中,还有一个while…else…的语句。while后面的else作用是指,当while循环正常执行完之后,如果中间没有被break终止的话,那么最后就会执行else后面的语句
index = 1
while index < 6:
print(index)
index += 1
else:
print("正常执行完后执行")
输出如下:
1
2
3
4
5
正常执行完后执行
# 如果之前的代码被break中断了,那么就不会执行else内的语句
运算有多种:包括算数运算、比较运算、赋值运算、逻辑运算、成员运算等等
无非就是加减乘除取模幂咯
print(9 + 2)
print(9 - 2)
print(9 * 2)
print(9 / 2)
print(9 // 2) # 得到整数部分 4
print(9 % 2) # 得到余数部分 1
print(9 ** 2) # 幂运算9的平方 81
print("python *" * 10) # 输出10个python
用于比较,结果是布尔值 True or False
对比学习法,都差不多
注意:在没有 ( ) 的情况下not 优先级高于 and,and优先级高于or,即优先级关系为( )>not>and>or,同一优先级从左往右计算。
除了以上一些基本的运算外,python还支持成员运算
print("p" in "python") # True
print("p" in "java") # False
print("p" not in "javascript") # False
"""
格式化字符 %
1、%s:字符串
2、%d: 有符号十进制整数,%06d表示输出的整数显示位数,不足的话用0补齐
3、%f: 浮点数,%.2f表示小数点后只显示两位小数
4、%%:输出%
"""
name = "浩明"
print("大家好,我叫%s,多多关照" % name) # 大家好,我叫浩明,多多关照
id = 1
print("我的学号是: %05d" % id) # 我的学号是: 00001
price = 12.4
weight = 23
money = price * weight
print('单价是:%.2f,重量是:%d,总的价格是:%.2f' % (price, weight, money)) # 单价是:12.40,重量是:23,总的价格是:285.20
# 输出%
percent = 0.252
print('数据比例是: %.1f%%' % (percent * 100)) # 数据比例是: 25.2%
Python中常用的数据类型有多种:整数(int) ,字符串(str),布尔值(bool),列表(list),元组(tuple),字典(dict),集合(set).
int,就是我们常见的数据类型,主要是用于运算:加减乘除之类的
之前也讲过,布尔值就两种:True,False,就是反应条件的正确与否
这里再讲下int,boolean,str三种类型之间的转换
# int-------> boolean
a = 1
print(bool(a)) # True 非零即为True
b = 0
print(bool(b)) # False
# boolean------> int
t = True
print(int(t)) # 1 True --> 1
t = False
print(int(t)) # 0 False --> 0
# int ---> str
i1 = 100
print(str(i1)) # '100'
# str ---> int # 全部由数字组成的字符串才可以转化成数字
s1 = '90'
print(int(s1)) # 90
# str ---> bool
s1 = '浩明'
s2 = ''
print(bool(s1)) # True 非空即True
print(bool(s2)) # False
# bool ---> str
t1 = True
print(str(True)) # 'True'
之前也说过,在python中,凡是被引号引用的都是字符串
索引
索引就是下标,从0开始
a = 'ABCD'
print(a[0]) # A
print(a[1]) # B
print(a[2]) # C
print(a[3]) # D
切片
切片就是通过索引(索引:索引:步长)以此来截取字符串的一部分,形成新的字符串
a = 'ABCDEFGHIHJK'
print(a[0:3]) # ABC print(a[:3]) 如果开头为0的话可以省略
print(a[2:5]) # CDE
print(a[:]) # ABCDEFGHIHJK 默认取所有
print(a[0:5:2]) # 加步长 ACE
字符串除了可以使用切片之外,还有一些其他的操作方法
用来计算字符串中某个元素出现的个数
str = 'ABCDEFGHIJK'
num = str.count('A')
print(num) # 1
num = str.count('A', 1, 4) # 支持切片操作
print(num) # 0
count = len(str) # len()用于计算整个字符串的长度
print(count) # 11
判断开头和结尾
str = 'ABCDEFGHIJK'
flag = str.startswith('A') # 也是可以支持切片的
print(flag) # True
flag = str.endswith('K')
print(flag) # True
切割字符串,最终会形成一个列表,这个列表不含有分割的这个元素
str = 'mybatis@spring@springmvc@springboot@springcloud'
list = str.split('@')
print(list) # ['mybatis', 'spring', 'springmvc', 'springboot', 'springcloud']
与split类似,只不过是从后面开始切,还可以指定切割的次数
str = 'pyton@java@linux'
list = str.rsplit('@', 1)
print(list) # ['pyton@java', 'linux'] ,从后面开始切,并且只切割一次
格式化输出
res = '{} {} {}'.format('小明', 18, 'male')
print(res) # 小明 18 male
res='{1} {0} {1}'.format('小明',18,'male') # 这里取的是对应下标的元素
print(res) # 18 小明 18
res='{name} {age} {sex}'.format(sex='male',name='小明',age=18)
print(res) # 小明 18 male
跳过字符串
str = '@hello@@123@@'
print(str.strip('@')) # 跳过首尾出现的@
print(str.lstrip('@'))# 跳过左边的@
print(str.rstrip('@'))# 跳过右边的@
hello@@123
hello@@123@
@hello@@123
字符串替换
str = 'my name is Bob,and Bob is my name'
print(str.replace('name', 'first_name', 1)) # 替换1处
print(str.replace('name', 'first_name', 2)) # 替换2处
my first_name is Bob,and Bob is my name
my first_name is Bob,and Bob is my first_name
都是找到元素对应的索引,find找不到就返回-1,index找不到就会报错,这是区别
str = 'ABCDEFG'
print(str.find('A')) # 0
print(str.find('K')) # -1 ,找不到返回-1
str = 'ABCDEFG'
print(str.index('A')) # 0
print(str.index('K')) # 找不到就会报错
控制大小写
str = 'hello pihao'
print(str.capitalize()) # 字符串首字母大写 Hello pihao
print(str.title()) # 每个单词的首字母大写 Hello Pihao
print(str.swapcase()) # 大小写翻转 HELLO PIHAO
中间居中,补齐
str = 'python'
print(str.center(20, '*')) # *******python*******
类似java中的数组[ ],中间的元素用逗号分隔。列表是有序的,并且存在索引,方便取值
# 列表的创建有三种方式
# 方式一(常用)
l1 = ['python', 'java', True, 123]
# 方式二(不常用)
l2 = list() # 创建一个空列表
# l2 = list(iterable) 里面是一个可迭代对象
l2 = list("abc")
print(l2) # ['a', 'b', 'c']
# 方式三(列表推导式)
l3 = [i for i in range(1, 5)]
print(l3) # [1, 2, 3, 4]
l1 = ['a', 'b', 'c', 1, 2, 3, True]
print(l1[0]) # a
print(l1[-1]) # True
print(l1[:]) # ['a', 'b', 'c', 1, 2, 3, True]
print(l1[:6:2]) # ['a', 'c', 2]
print(l1[::2]) # ['a', 'c', 2, True]
print(l1[::-1]) # [True, 3, 2, 1, 'c', 'b', 'a']
name_list = ['zhangsan', 'lisi', 'wangwu']
name_list.append('王小二') # append:在列表的末尾添加数据
print(name_list) # ['zhangsan', 'lisi', 'wangwu', '王小二']
name_list = ['zhangsan', 'lisi', 'wangwu']
name_list.insert(1, '小妹妹') #在列表的指定位置插入数据
print(name_list) # ['zhangsan', '小妹妹', 'lisi', 'wangwu']
name_list = ['zhangsan', 'lisi', 'wangwu']
temp_list = ['孙悟空', '猪八戒'] # extend:拼接列表
name_list.extend(temp_list)
print(name_list) # ['zhangsan', 'lisi', 'wangwu', '孙悟空', '猪八戒']
删除指定索引处的元素
list = ['python', 'java', 'js', 'c', 'c++', 'c#']
list.pop() # 不传参数默认删除列表最后一个,返回删除的元素
print(list) # ['python', 'java', 'js', 'c', 'c++']
list.pop(1) # 删除指定索引处的元素,返回删除的元素
print(list) # ['python', 'js', 'c', 'c++']
通过元素删除列表中的该元素
list = ['python', 'java', 'js', 'c', 'c++', 'c#']
list.remove('js')
print(list) # ['python', 'java', 'c', 'c++', 'c#']
清空列表中的所有元素
list = ['python', 'java', 'js', 'c', 'c++', 'c#']
list.clear()
print(list) # []
删除指定索引处的元素,适用于切片删除
list = ['python', 'java', 'js', 'c', 'c++', 'c#']
del list[0]
print(list) # ['java', 'js', 'c', 'c++', 'c#']
# 切片删除元素
list = ['python', 'java', 'js', 'c', 'c++', 'c#']
del list[1:]
print(list) # ['python']
# 切片+步长删除元素
list = ['python', 'java', 'js', 'c', 'c++', 'c#']
del list[::2]
print(list) # ['java', 'c', 'c#']
list = ['python', 'java', 'js', 'c', 'c++', 'c#']
list[0] = 'java'
print(list) # ['java', 'java', 'js', 'c', 'c++', 'c#']
list = ['python', 'java', 'js', 'c', 'c++', 'c#']
list[1:3] = 'abc'
print(list) # ['python', 'a', 'b', 'c', 'c', 'c++', 'c#']
list = ['python', 'java', 'js', 'c', 'c++', 'c#']
list[::2] = 'xyz'
print(list) # ['x', 'java', 'y', 'c', 'z', 'c#']
切片查,或者使用循环遍历
统计列表中某个元素出现出现的次数
list = ['python', 'java', 'js', 'python', 'c++', 'c#']
print(list.count('python')) # 2
找出某个元素第一次所在的索引
list = ['python', 'java', 'js', 'python', 'c++', 'c#']
print(list.index('java')) # 1
print(list.index('go')) # 找不到就报错
用于在原位置将列表排序
list = [3, 2, 1, 4, 5]
list.sort() # 会直接怼列表进行排序
print(list) # [1, 2, 3, 4, 5]
# sorted的区别:sorted内置函数,不会改变原有的数据,而是生成一个新的结果,如果是元组的话,结果也是返回一个有序的列表,而不再是元组了
x = sorted(list)
print(x)
# sort()方法不支持直接对字典排序,如果需要对字典排序
dic = [
{
'name': 'Bob', 'age': 20},
{
'name': 'Jack', 'age': 21},
]
def func(ele):
return ele['age']
# key的参数类型是函数
dic.sort(key=func)
# 或者使用匿名函数(推荐使用)
dic.sort(key=lambda ele: ele['age'])
print(dic)
将列表中的元素反向存放
list = ['python', 'java', 'js', 'c++', 'c#']
list.reverse()
print(list) # ['c#', 'c++', 'js', 'java', 'python']
list1 = ['python', 'java', 'js']
list2 = ['php', 'html']
print(list1 + list2) # ['python', 'java', 'js', 'php', 'html']
print(list1 * 2) # ['python', 'java', 'js', 'python', 'java', 'js']
在循环一个列表时的过程中,如果你要改变列表的大小(增加值,或者删除值),那么结果很可能会出错或者报错。
# 错误示范
alist = [1,1,2,2,3,3,2,2,1,1]
for i in alist:
if i ==1:
alist.remove(1)
print(alist)
# 输出 [2, 2, 3, 3, 2, 2, 1, 1],按道理我们是想把所有的1都删除
错误原因:删除列表元素,导致列表内容改变,部分元素位置前移;当继续进行for循环时,索引继续加一,导致跳过一个元素。
**解决办法一:**alist[:]
alist = [1,1,2,2,3,3,2,2,1,1]
for i in alist[:]:
if i ==1:
alist.remove(1)
print(alist)
解决办法二:定义一个新的列表
alist = [1,1,2,2,3,3,2,2,1,1]
alist_new = []
for i in alist:
if i!=1:
alist_new.append(i)
alist = alist_new
print (alist)
解决办法三:改变循环条件
alist = [1, 1, 2, 2, 3, 3, 2, 2, 1, 1]
i = 0
while i < len(alist):
if alist[i] == 1:
alist.pop(i)
i -= 1
i += 1
print(alist) # [2, 2, 3, 3, 2, 2]
对于之前学过的list,我们知道它可以进行增删查改的操作,安全性不高 ! 但如果是一些重要的数据呢?我们希望它只能够查看而不能修改,所以python就提供了这样一种数据类型,就是元组,也就是不可变的列表。
tu1 = ('a', 'c', 'd', 1, 2, 3, True)
print(tu1[0]) # a
print(tu1[-1]) # True
print(tu1[1:3]) # ('c', 'd')
print(tu1[::2]) # ('a', 'd', 2, True)
print(tu1[::-1]) # (True, 3, 2, 1, 'd', 'c', 'a')
因为元组的特性,直接从属于元组的元素不能更改,只能查看
# 使用for循环遍历元组
tu1 = ('a', 'c', 'd', 1, 2, 3, True)
for i in tu1:
print(i)
通过元素找索引(可切片),找到第一个元素就返回,找不到就会报错
tu1 = ('a', 'c', 'd', 1, 2, 3, True)
print(tu1.index('d')) # 2
获取某元素在列表中出现的次数
tu1 = ('a', 'c', 'd', 1, 2, 3, True)
print(tu1.count('d')) # 1
获取长度
tu1 = ('a', 'c', 'd', 1, 2, 3, True)
print(len(tu1)) # 7
你可以理解成java中的map集合,用来存放键值对的
回顾:python中的数据类型如果按照可变和不可变来分类的话
不可变数据类型(可哈希):int,str,bool,tuple
可变数据类型(不可哈希):list,dict,set
字典是python语言中的映射类型,它是以 { } 括起来的,里面存的是键值对
Key:不可变(可哈希)的数据类型,并且键是唯一的,不能重复
Value:任意数据类型,没有限制。
注意:在python3.5之前,字典是无序的
在python3.6之后,字典会是有序的。
字典的创建有很多种方式
dic = dict((('one', 1), ('two', 2), ('three', 3)))
print(dic) # {'one': 1, 'two': 2, 'three': 3}
dic = dict(one=1, two=2, three=3)
print(dic) # {'one': 1, 'two': 2, 'three': 3}
dic = dict({
'one': 1, 'two': 2, 'three': 3})
print(dic) # {'one': 1, 'two': 2, 'three': 3}
# 先了解
dic = dict(zip(['one', 'two', 'three'],[1, 2, 3]))
print(dic)
# 字典推导式,先了解
# dic = { k: v for k,v in [('one', 1),('two', 2),('three', 3)]}
# print(dic)
通过键值对直接添加
dic = {
'name': '浩明', 'age': 18}
dic['weight'] = 55 # 没有weight这个字段,就会增加这个键值对
print(dic) # {'name': '浩明', 'age': 18, 'weight': 55}
dic['name'] = '小明' # 有name这个字段,那么就修改value值
print(dic) # {'name': '小明', 'age': 18, 'weight': 55}
# setdefault的使用
dic = {
'name': '浩明', 'age': 18}
dic.setdefault("weight", 55) # 没有weight键,就会添加
print(dic)
dic.setdefault("name", "小皮") # 有这个字段,就不会添加
print(dic)
# 另外setdefault是有返回值的
value = dic.setdefault("name", 'x')
print(value) # 浩明
pop通过key删除字典的键值对,有返回值
dic = {
'name': '浩明', 'age': 18}
age = dic.pop('age', 'age')
value = dic.pop("weight", 55) # 如果没有这个字段的时候可以设置默认的返回值
print(value) # 55
print(age) # 18
print(dic) # {'name': '浩明'}
在3.5之前,popitem为随机删除,在3.6之后改为删除最后一个键值对,有返回值
dic = {
'name': '浩明', 'age': 18}
res = dic.popitem() # 返回一个元组
print(res) # ('age', 18)
print(dic) # {'name': '浩明'}
清空字典
dic = {
'name': '浩明', 'age': 18}
dic.clear()
print(dic) # {}
通过键删除键值对
dic = {
'name': '浩明', 'age': 18}
del dic['name']
print(dic) # {'age': 18}
del dic # 删除整个字典
dic = {
'name': '浩明', 'age': 18}
dic['name'] = '小皮'
print(dic) # {'name': '小皮', 'age': 18}
dic = {
'name': '浩明', 'age': 18}
dic.update(age=55, gender='male')
print(dic) # {'name': '浩明', 'age': 55, 'gender': 'male'}
dic = {
'name': '浩明', 'age': 18}
dic.update([('weight', 55), ('gender', 'male')])
print(dic) # {'name': '浩明', 'age': 18, 'weight': 55, 'gender': 'male'}
dic1 = {
'name': '浩明', 'age': 18}
dic2 = {
'weight': 55, 'gender': 'male'}
dic1.update(dic2)
print(dic1) # {'name': '浩明', 'age': 18, 'weight': 55, 'gender': 'male'}
print(dic2) # {'weight': 55, 'gender': 'male'}
dic1 = {
'name': '浩明', 'age': 18}
print(dic1['name']) # 浩明,如果 没有这个键的话就会报错
dic = {
'name': '浩明', 'age': 18}
value = dic.get('name')
print(value) # 浩明
value = dic.get('gender') # 如果没有的话返回None
print(value) # None
value = dic.get('gender', 'male') # 如果没有返回默认设置的值
print(value) # male
dic = {
'name': '浩明', 'age': 18}
keys = dic.keys() # 返回所有的key的集合
print(keys) # dict_keys(['name', 'age'])
dic = {
'name': '浩明', 'age': 18}
vals = dic.values() # 返回所有值的集合
print(vals) # dict_values(['浩明', 18])
dic = {
'name': '浩明', 'age': 18}
items = dic.items();
print(items) # dict_items([('name', '浩明'), ('age', 18)])
dic = {
'name': '浩明', 'age': 18}
keys = dic.keys(); # 这是一个高仿列表,可以将其转化为列表
print(keys) # dict_keys(['name', 'age'])
list1 = list(keys)
print(list1) # ['name', 'age']
# 字典的遍历
dic = {
'name': '浩明', 'age': 18}
for i in dic: # 这里的dic相当于dic.keys()
print(i) # 遍历所有的key
for i in dic.values(): # 遍历所有的value
print(i)
dic = {
'name': '浩明', 'age': 18}
for i in dic.items():
print(i)
# 输出
('name', '浩明')
('age', 18)
dic = {
'name': '浩明', 'age': 18}
for i, j in dic.items():
print('键: %s' % i)
print('值:%s' % j)
# 输出
键: name
值:浩明
键: age
值:18
在循环一个字典的过程中,不要改变字典的大小(增,删字典的元素),这样会直接报错。
dic = dict({
'name': 'hao', 'age': 18})
for i in dic.keys():
if 'n' in i:
del dic[i]
print(dic)
#报错 RuntimeError: dictionary changed size during iteration
解决办法:
a = {
1:0,2:1,3:0,4:1}
list1 = []
list2 = []
for k,v in a.items():
if v !=0:
list1.append(k)
list2.append(v)
a = dict(zip(list1,list2))
print(a)
类似java中的hashset,set集合中的元素是无序的,不可重复的,它里面的元素是可哈希的(不可变类型),但是set集合本身是不可哈希的(所以set集合做不了字典的键)。它可以帮你实现自动去重。我记得redis中也有类似的场景:取交集、差集、并集
set1 = set({
1, 2, 'set', True})
set2 = {
1, 2, 'set', True}
print(set1, set2) # {1, 2, 'set'} {1, 2, 'set'}
set1 = {
'java', 'python', 'linux'}
set1.add('php')
print(set1) # {'linux', 'python', 'php', 'java'}
# 迭代着增加
set1.update([1, 2, 3])
print(set1) # {'java', 1, 2, 3, 'python', 'php', 'linux'}
直接删除某个值
set1 = {
'java', 'python', 'linux'}
set1.remove('linux')
print(set1) # {'python', 'java'}
随机删除一个元素
set1 = {
'java', 'python', 'linux'}
res = set1.pop()
print(res) # python(随机的)
print(set1) # {'linux', 'java'}
清空集合
删除集合这个变量
求交集
set1 = {
'java', 'python', 'linux'}
set2 = {
'java', 'html', 'linux'}
print(set1 & set2) # {'java', 'linux'}
print(set1.intersection(set2)) # {'java', 'linux'}
求差集
set1 = {
'java', 'python', 'linux'}
set2 = {
'java', 'html', 'linux'}
print(set1 - set2) # {'python'}
print(set1.difference(set2)) # {'python'}
求并集
set1 = {
'java', 'python', 'linux'}
set2 = {
'java', 'html', 'linux'}
print(set1 | set2) # {'python', 'html', 'linux', 'java'}
print(set1.union(set2)) # {'python', 'html', 'linux', 'java'}
反交集
子集与超集
# 遍历字符串
msg = '今天又是划水的一天'
for i in msg:
print(i)
# 遍历列表
l1 = ['java', 'python', 'linux']
for i in l1:
print(i)
# 遍历字典
dic = {
'name': "xiapi", 'age': 18, 'gender': 'male'}
for k, v in dic.items():
print(k, v)
# 完成的for循环
for num in [1, 2, 3]:
print(num)
if num == 6:
break
else: # 当上述循环完整的遍历之后就会执行else中的代码,如果有break,那么就不会执行
print("会执行嘛?")
print("循环结束")
对于一个可迭代的iterable、可遍历的对象(字符串、列表),enumerate可以将其组成一个索引序列,利用它可以同时获得索引和值
l1 = ['java', 'python', 'linux', 'php']
for i in enumerate(l1):
print(i)
#输出如下:
(0, 'java')
(1, 'python')
(2, 'linux')
(3, 'php')
l1 = ['java', 'python', 'linux', 'php']
for index, value in enumerate(l1, 10): # 这个地方可以设置初始的索引值,默认是0
print(index, value)
# 输出如下:
10 java
11 python
12 linux
13 php
指定范围,生成指定数字
for i in range(1, 10):
print(i) # 1~9
for i in range(1, 10, 2): # 指定步长
print(i) # 1,3,5,7,9
先讲一下 is 和 == 的区别,== 是判断两个对象的内容是否相等,而 is 是判断两个对象的内存地址是否相等。可以使用 id( ) 方法查看对象的内存地址
python在执行同一个代码块的初始化对象的命令时,会检查是否其值是否已经存在,如果存在,会将其重用,在内存中只有一个,id相同
# 同一个代码块下
num1 = 1024
num2 = 1024
print(id(num1)) # 39723920
print(id(num2)) # 39723920
print(num1 is num2) # True is 用来判断两个对象的内存地址是否相同
Python自动将-5~256的整数进行了缓存,当你将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象。
python会将一定规则的字符串在字符串驻留池中,创建一份,当你将这些字符串赋值给变量时,并不会重新创建对象, 而是使用在字符串驻留池中创建好的对象。
先看赋值运算
list1 = ['java', 'python', 'linux']
list2 = list1
list1[0] = 'php'
print(list1) # ['php', 'python', 'linux']
print(list2) # ['php', 'python', 'linux']
# list1、list2指向的是同一个列表,任何一个变量对列表进行改变,剩下那个变量在使用列表之后,这个列表就是发生改变之后的列表
list1 = ['java', 'python', 'linux']
list2 = list1.copy()
print(id(list1), id(list2)) # 31330496 31331328 这里列表的地址是不一样的
print(id(list1[0]), id(list2[0])) # 31302128 31302128 但是里面的元素的地址是相同的
print(id(list1[1]), id(list2[1])) # 31667696 31667696
#
对于浅copy来说,只是在内存中重新创建了开辟了一个空间存放一个新列表,但是新列表中的元素与原列表中的元素是公用的。
import copy
list1 = ['java', True, (1, 2, 3), [11, 22]]
list2 = copy.deepcopy(list1)
print(id(list1), id(list2)) # 39838144 39729472 不同
print(id(list1[0]), id(list2[0])) # 39035376 39035376 相同
print(id(list1[1]), id(list2[1])) # 8790985246544 8790985246544 相同
print(id(list1[2]), id(list2[2])) # 39709120 39709120 相同
print(id(list1[3]), id(list2[3])) # 41044928 41045248 不同
对于深copy来说,列表是在内存中重新创建的,列表中可变的数据类型是重新创建的,列表中的不可变的数据类型是公用的。
文件操作固定套路:打开文件,读写文件,关闭文件
以只读方式打开文件,文件的指针将会放在文件的开头。是文件操作最常用的模式,也是默认模式,如果一个文件不设置mode,那么默认使用r模式操作文件。
# read()方法
# 参数解析
# file:文件路径
# mode: 操作文件的模式
# encoding: 指定编码
file = open(file=r'file.txt', mode='r', encoding='utf-8')
content = file.read()
print(content)
file.close()
## 输出
python
java
linux
# 分析:该种文件读取方式是将文件的全部内容都读取出来,有很大的弊端,如果文件很大那么就非常占用内存,容易导致奔溃
# read(n)方法,n按照字符读取
file = open(file=r'file.txt', mode='r', encoding='utf-8')
content = file.read(6) # 只读取6个字符,然后下次的读取就从这里开始读了
content2 = file.read()
print(content)
print('*' * 10)
print(content2)
file.close()
# 输出
hello
**********
world python
java
linux
# readline()
# readline()读取每次只读取一行,注意点:readline()读取出来的数据在后面都有一个\n
file = open(file=r'file.txt', mode='r', encoding='utf-8')
content = file.readline()
content2 = file.readline()
content3 = file.readline()
print(content)
print(content2)
print(content3)
file.close()
# 输出
hello
java
linux
# 解决办法:将每次读取出来后的数据加一个strip()
file = open(file=r'file.txt', mode='r', encoding='utf-8')
content = file.readline().strip()
content2 = file.readline().strip()
content3 = file.readline().strip()
print(content)
print(content2)
print(content3)
file.close()
# 输出(这下就没有 \n换行了)
hello
java
linux
# readlines() 返回一个列表,列表里面每个元素是原文件的每一行,如果文件很大,占内存,容易崩盘。
file = open(file=r'file.txt', mode='r', encoding='utf-8')
list1 = file.readlines();
print(list1)
# 输出
['hello\n', 'java\n', 'linux\n']
# 可以通过for循环去读取,文件句柄是一个迭代器,他的特点就是每次循环只在内存中占一行的数据,非常节省内存。
file = open(file=r'file.txt', mode='r', encoding='utf-8')
for line in file:
print(line)
file.close()
以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。记住下面讲的也是一样,带b的都是以二进制的格式操作文件,他们主要是操作非文字文件:图片,音频,视频等,并且如果你要是带有b的模式操作文件,那么不用声明编码方式。
pic = open(file='bg.jpg', mode='rb')
content = pic.read()
print(content)
# 输出一大串看不懂的二进制数据
往文件中写内容,也有很多种模式w,wb,w+,w+b
如果文件不存在,就会先创建文件再写入内容,如果文件存在,先清空文件内容再写入
file = open(file='abc.txt', mode='w')
file.write('hello java')
file.close()
以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如:图片,音频,视频等
打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
file = open(file='file.txt', mode='a', encoding='utf-8')
file.write('123')
file.close()
文件操作模式还有一种 ’+‘模式,意为读写,但是效率比较低,不经常使用
之前我们都是通过open打开的,其实pyhton还提供了另一种方式:with open( ) as …的形式
with open(file='file.txt', encoding='utf-8') as f1:
f1.read()
with open(file='abc.txt', encoding='utf-8') as f2, \
open(file='file.txt', encoding='utf-8', mode='w') as f2:
f1.write(f2.read())
def 函数名():
函数体
使用函数名加小括号就可以调用了 写法:函数名() 这个时候函数的函数体会被执行
def sum():
return 1 + 1
print(sum()) # 2
def sum():
return 1 + 1
注意:遇到return,函数结束,return下面的(函数内)的代码不会执行。
def info(name, weight):
print('hello,my name is %s,weight is %.2f kg' % (name, weight))
info('pihao', 55.3)
由此可见,我们想要调用一个方法时,必须要记住参数的位置。这样不利于操作,所有python为我们提供了一种关键字参数,我们就不需要再去记忆参数所在的位置了
def info(name, weight):
print('hello,my name is %s,weight is %.2f kg' % (name, weight))
info(name='pihao',weight=56)
在函数声明的时候, 就可以给出函数参数的默认值. 默认值参数一般是这个参数使用率较高,才会设置默认值参数
def stu_info(name, age, sex='男'):
print("录入学生信息")
print(name, age, sex)
print("录入完毕")
stu_info("张强", 18)
动态参数分为两种:动态接受位置参数 *args,动态接收关键字参数**kwargs.
动态接收位置参数:*args
def names(*args):
print('姓名:', args)
names('小花', '小黄', '小兰')
*动态接收关键字参数: *kwargs
**kwargs,是接受所有的关键字参数然后将其转换成一个字典赋值给kwargs这个形参。
def func(**kwargs):
print(kwargs)
func(name='pihao', age=18, gender='male') # {'name': 'pihao', 'age': 18, 'gender': 'male'}
聚合打散
def func(*args):
print(args)
func(*'hello') # ('h', 'e', 'l', 'l', 'o')
dic1 = {
'name': '小白', 'age': 18}
dic2 = {
'hobby': '看书', 'sex': '男'}
def func(**kwargs):
print(kwargs)
func(**dic1,**dic2) # {'name': '小白', 'age': 18, 'hobby': '看书', 'sex': '男'}
*args一定要在位置参数与默认值参数中间:位置参数,*args,默认参数。
*位置参数,*args,默认参数,*kwargs。
这三个空间的加载顺序为:内置命名空间、全局命名空间、局部命名空间
取值顺序:局部,全局,内置
作用域就是作用范围, 按照生效范围来看分为全局作用域和局部作用域
# 在全局作用域下打印,则他们获取的都是全局作用域的所有的内容。
a = 2
b = 3
print(globals())
print(locals())
'''
{'__name__': '__main__', '__doc__': None, '__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001806E50C0B8>,
'__spec__': None, '__annotations__': {},
'__builtins__': ,
'__file__': 'D:/lnh.python/py project/teaching_show/test/function.py',
'__cached__': None, 'a': 2, 'b': 3}
'''
# 在局部作用域中打印。
a = 2
b = 3
def foo():
c = 3
print(globals()) # 和上面一样,还是全局作用域的内容
print(locals()) # {'c': 3}
foo()
先来看一个现象
a = 1
def func():
print(a)
func()
a = 1
def func():
a += 1 # 报错
func()
局部作用域对全局作用域的变量(此变量只能是不可变的数据类型)只能进行引用,而不能进行改变,只要改变就会报错,但是有些时候,我们程序中会遇到局部作用域去改变全局作用域的一些变量的需求,这怎么做呢?这就得用到关键字global
global第一个功能:在局部作用域中可以更改全局作用域的变量。
count = 1
def search():
global count
count = 2
search()
print(count) # 2
利用global在局部作用域也可以声明一个全局变量。
def func():
global a
a = 3
func()
print(a)
总结
global关键字有两个作用:
函数名指向的是这个函数的内存地址
def func():
print("呵呵")
print(func) #
def func():
print("呵呵")
print(func)
a = func # 把函数当成一个变量赋值给另一个变量
a() # 函数调用 func()
def func1():
print("in func1: 嘻嘻")
def func2():
print("in func2: 哈哈")
def func3():
print("in func3: 咯咯")
def func4():
print("in func4: 吱吱")
lst = [func1, func2, func3, func4] # 注意:这里存进去的不是字符串
for i in lst:
i()
def func1():
print('in func1')
def func2(f):
print('in func2')
f()
func2(func1)
def func1():
print('in func1')
def func2(f):
print('in func2')
return f
ret = func2(func1)
ret() # ret, f, func1 都是指向的func1这个函数的内存地址
小结:函数名是一个特殊的变量,他除了具有变量的功能,还有最主要一个特点就是加上() 就执行,其实他还有一个学名叫第一类对象
f-strings 是python3.6开始加入标准库的格式化输出新的写法,这个格式化输出比之前的%s 或者 format 效率高并且更加简化,非常的好用
name = '小明'
age = 20
gender = '男'
msg = f'姓名:{name},年龄:{age},性别:{gender}'
msg2 = F'姓名:{name},年龄:{age},性别:{gender}'
print(msg)
print(msg2)
## 输出如下:
姓名:小明,年龄:20,性别:男
姓名:小明,年龄:20,性别:男
print(f'{3 * 21}') # 63
name = 'barry'
print(f"全部大写:{name.upper()}") # 全部大写:BARRY
# 字典也可以
teacher = {
'name': '小明', 'age': 18}
msg = f"The teacher is {teacher['name']}, aged {teacher['age']}"
print(msg) # The teacher is 小明, aged 18
# 列表也行
l1 = ['小明', 18]
msg = f'姓名:{l1[0]},年龄:{l1[1]}'
print(msg) # 姓名:小明,年龄:18
也可以完成函数的相应功能
def sum_a_b(a,b):
return a + b
a = 1
b = 2
print('求和的结果为' + f'{sum_a_b(a,b)}')
name = 'barry'
age = 18
ajd = 'handsome'
speaker = f'Hi {name}.'\
f'You are {age} years old.'\
f'You are a {ajd} guy!'
print(speaker) # Hi barry.You are 18 years old.You are a handsome guy!
总结:f-string的格式化输出更加简洁,方便,易读。而且他的处理速度对之前的%s 或者format 有了较高的提升,所以以后尽量使用此种格式化输出。
在python中,但凡内部含有__iter__方法的对象,都是可迭代对象。
查看对象内部的方法
str = 'python'
print(dir(str)) #
dir()会返回一个列表,这个列表中含有该对象的以字符串的形式所有方法名。这样我们就可以判断python中的一个对象是不是可迭代对象了
str = 'python'
i = 100
print('__iter__' in dir(str)) #True,说明字符串是一个可迭代对象
print('__iter__' in dir(i)) # False,数字不是一个可迭代对象
在python中,内部含有’Iter’方法并且含有’next’方法的对象就是迭代器
o1 = 'alex'
o2 = [1, 2, 3]
o3 = (1, 2, 3)
o4 = {
'name': '太白','age': 18}
o5 = {
1, 2, 3}
f = open('file',encoding='utf-8', mode='w')
print('__iter__' in dir(o1)) # True
print('__iter__' in dir(o2)) # True
print('__iter__' in dir(o3)) # True
print('__iter__' in dir(o4)) # True
print('__iter__' in dir(o5)) # True
print('__iter__' in dir(f)) # True
# hsagn
print('__next__' in dir(o1)) # False
print('__next__' in dir(o2)) # False
print('__next__' in dir(o3)) # False
print('__next__' in dir(o4)) # False
print('__next__' in dir(o5)) # False
print('__next__' in dir(f)) # True
f.close()
通过以上代码可以验证,之前我们学过的这些对象,只有文件句柄是迭代器,剩下的那些数据类型都是可迭代对象。
l1 = [1, 2, 3, 4, 5, 6]
obj = l1.__iter__()
print(obj) #
可迭代对象是不可以一直迭代取值的(除去用索引,切片以及Key),但是转化成迭代器就可以了,迭代器是利用__next__()进行取值
l1 = [1, 2, 3, 4, 5, 6]
obj = l1.__iter__()
print(obj)
print(obj.__next__())
print(obj.__next__())
print(obj.__next__())
print(obj.__next__())
print(obj.__next__())
print(obj.__next__())
l1 = [1, 2, 3, 4, 5, 6]
# 1 将可迭代对象转化成迭代器
obj = iter(l1)
# 2,利用while循环,next进行取值
while 1:
# 3,利用异常处理终止循环
try:
print(next(obj))
except StopIteration:
break
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象。
def func():
print(11) # 没有输出
yield 22
res = func() # 这个时候并不会执行函数,只是返回一个生成器
print(res)
# 输出如下:
<generator object func at 0x00000000025C0F90>
a = res.__next__() # 这个时候才会执行函数
print(a)
b = next(res)
print(b) # 也会执行函数
import sys
def fibonacci(n): # 生成器函数-斐波那契数列
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10)
while True:
try:
print(next(f), end=' ')
except StopIteration:
sys.exit()
当程序运行完最后一个yield,那么后面继续运行next()程序会报错,一个yield对应一个next,next超过yield数量,就会报错,与迭代器一样。
除了使用def关键字定义一个函数外,我们还可以使用lambda表达式定义一个函数,这个就有点像java1.8新特性中的stream流的使用
基本语法
lambda x, y: x + y
匿名函数的使用
def func(a, b, fn):
c = fn(a, b)
return c
x1 = func(1, 2, lambda a, b: a + b)
print(x1)
x2 = func(1, 2, lambda a, b: a - b)
print(x2)
x3 = func(1, 2, lambda a, b: a * b)
print(x3)
x4 = func(1, 2, lambda a, b: a / b)
print(x4)
filter对可迭代对象进行过滤,得到的是一个filter对象
python2的时候是内置函数,pyhton3修改成了一个内置类
ages = [12, 23, 30, 56, 83, 35]
# 过滤,选出大于35的数字
# filter可以给定两个参数,第一个参数是函数,第二个参数可迭代对象
# filter的结果是一个filter类型的对象(也是可迭代对象)
x = filter(lambda ele: ele > 35, ages)
print(x) #
print('__iter__' in dir(x)) # True 判断是不是可迭代对象
for i in x:
print(i)
ages = [12, 23, 30, 56, 83, 35]
m = map(lambda ele: ele + 2, ages)
print(list(m)) # 将map转化为list列表
# 输出 [14, 25, 32, 58, 85, 37]
from functools import reduce
ages = [12, 23, 30, 56, 83, 35]
scores = reduce(lambda x, y: x + y, ages)
print(scores) # 239 求和
dic = [{
'name': '小明', 'age': 18}, {
'name': '小花', 'age': 20}]
# 求字典内所有人年龄的总和
sum = reduce(lambda x, y: x + y['age'], dic, 0) # 新的用法(初始化为0)
print(sum) # 38
取绝对值
求两个数的商和余数,返回一个元组
求最大值
求最小值
幂运算
四舍五入,保留到指定小数位
用来求和的
如果所有的元素转成布尔值都是True,那结果就是True
只要有一个专为布尔值为True,那结果就是True
排序
将数字转换成二进制
将字符编码转成对应的字符 chr(97)= a
将字符专为编码 ord(‘a’) = 97
执行字符串里面的python代码,有注入风险,不用
以指定的退出吗结束程序
获取对象的内存地址
先来看个例子,其实也就是函数的名字作为返回值的用法
def outer():
m = 100
print('我是outer函数')
def inner(): # inner函数只能在outer函数内部可见
print('我是inner函数')
reutrn inner # 返回内部函数的方法名
outer()
# inner() 这里会报错,无法访问inner函数
记住闭包的格式,有一个局部变量,然后在内部函数中修改了变量的值
def outer():
m = 100
print('我是outer函数')
def inner():
return m + 1
return inner # inner函数只能在outer函数内部可见
print(outer()()) # 101
nonlocal的使用
# 在内部函数如何修改外部函数的局部变量
def outer():
x = 10 # 在外部函数里定义一个变量x,是一个局部变量
def inner():
# 在内部函数如何修改外部函数的局部变量
nonlocal x # 此时,这里的x不再是新增的变量,而是外部的局部变量x
y = x + 1
x = 20 # 不是修改外部的x变量,而是在inner函数内部又创建了一个新的变量x
return inner