Python Learning Journal:Day3
字符串
驻留机制
仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中。
对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会重新开辟新空间,而是将该字符串的地址赋给新创建的变量。
a = 'python'
b = "python"
c = '''python'''
print(a, id(a)) # python 1326564188912
print(b, id(b)) # python 1326564188912
print(c, id(c)) # python 1326564188912
查询
方法 | 作用 |
---|---|
index() | 查找子串substr第一次出现的位置,不存在ValueError |
rindex() | 查找子串substr最后出现的位置,不存在ValueError |
find() | 查找子串substr第一次出现的位置,不存在返回-1 |
rfind() | 查找子串substr最后出现的位置,不存在返回-1 |
建议使用 find 或 rfind 进行查找,不会报错
s = 'hello,hello'
print(s.index('lo')) # 3
print(s.find('lo')) # 3
print(s.rindex('lo')) # 9
print(s.rfind('lo')) # 9
print(s.index('k')) # 报错:ValueError: substring not found
print(s.find('k')) # -1
大小写转换
方法 | 作用 |
---|---|
upper() | 所有字符转大写 |
lower() | 所有字符转小写 |
swapcase() | 所有字符大写转小写、小写转大写 |
capitalize() | 首字母转大写、其余转小写 |
title() | 每个单词第一个字符转大写,每个单词其余字符转小写 |
s = 'hELlo woRLD'
print(s.upper()) # HELLO WORLD
print(s.lower()) # hello world
print(s.swapcase()) # HelLO WOrld
print(s.capitalize()) # Hello world
print(s.title()) # Hello World
内容对齐
方法 | 作用 |
---|---|
center() | 居中对齐,默认补空格 |
ljust() | 左对齐,默认补空格 |
rjust() | 右对齐,默认补空格 |
zfill() | 左侧补0 |
s = 'hello,python'
print(s.center(20, '*')) # ****hello,python****
print(s.ljust(20, '*')) # hello,python********
print(s.ljust(10, '*')) # hello,python
print(s.rjust(20, '*')) # ********hello,python
print(s.rjust(20)) # hello,python
print(s.zfill(20)) # 00000000hello,python
print('-8910'.zfill(10)) # -000008910
劈分
方法 | 作用 |
---|---|
split() | 从左边开始劈分 ,sep=分隔符,maxsplit=劈分次数、剩余部分单独做一部分 |
rsplit() | 从右边开始劈分 |
s = 'hello world python'
print(s.split()) # ['hello', 'world', 'python']
s1 = 'hello:world:python'
print(s1.split(sep=':')) # ['hello', 'world', 'python']
print(s1.split(sep=':', maxsplit=1)) # ['hello', 'world:python']
判断
方法 | 作用 |
---|---|
isidentifier() | 判断是否为合法的标识符(字母、数字、下划线) |
isspace() | 判断是否都为空白字符组成(回车、换行、水平制表符) |
isalpha() | 判断是否都为字母组成 |
isdecimal() | 判断是否全由十进制数字组成 |
isnumeric() | 判断是否全由数字组成 |
isalnum() | 判断是否全由字母、数字组成 |
s = 'hello,python'
print(s.isidentifier()) # False
print('hello'.isidentifier()) # True
print('张三'.isidentifier()) # True
print('123张三'.isidentifier()) # False
print('\t'.isspace()) # True
print('abc'.isalpha()) # True
print('张三'.isalpha()) # True
print('123'.isdecimal()) # True
print('123四'.isdecimal()) # False
print('123四'.isnumeric()) # True
print('ⅡⅣ'.isnumeric()) # True:罗马数字是数字
print('张三123'.isalnum()) # True
替换
方法 | 作用 |
---|---|
replace() | 三个参数:待替换子串、替换子串、替换个数 |
s = 'hello,python'
print(s.replace('python', 'java')) # hello,java
s1 = 'hello,python,python,python'
print(s1.replace('python', 'java', 2)) # 第三个参数为替换几个:hello,java,java,python
合并
方法 | 作用 |
---|---|
join() | 将列表或元组中的字符串合并成一个字符串 |
list1 = ['hello', 'world', 'python']
print('|'.join(list1)) # hello|world|python
print(' '.join(list1)) # hello world python
t = ('hello', 'world', 'python')
print('*'.join(t)) # hello*world*python
print('*'.join('python')) # 当作字符串序列:p*y*t*h*o*n
比较
运算符:>,<=,<,<=,==,!=
比较规则:从第一个字符开始依次比较
比较原理:ord()函数:获取原始值
chr()函数:通过value值获得字符
print('apple' > 'app') # True
print('apple' > 'banana') # False
print(ord('a'), ord('b')) # 97 98
print(chr(97), chr(98)) # a b
print(chr(26472)) # 杨
切片
不可变类型:不可进行增删改等操作
切片操作后将产生新的对象
s = 'hello,python'
print(s[:5]) # 由于没有指定开始位置,所以从第0个开始 hello
print(s[6:]) # 由于没有指定结束位置,所以到最后一个结束 python
print(s[1:12:2]) # el,yhn
格式化字符串
方法一:%作占位符:'我的名字叫:%s,今年%d岁了’ % (name, age)
方法二:{}作占位符,format()方法
方法三:{}作占位符,f-string
name = '张三'
age = 18
print('我的名字叫:%s,今年%d岁了' % (name, age)) # 我的名字叫:张三,今年18岁了
print('我叫{0},今年{1}岁,我真的叫{0}'.format(name, age)) # 我叫张三,今年18岁,我真的叫张三
print(f'我叫{name},今年{age}岁了') # 我叫张三,今年18岁了
自定义宽度+精度
print('%10d' % 99) # 99
print('%f' % 3.1415926) # 3.141593
print('%.3f' % 3.1415926) # .3表示小数点后三位:3.142
print('%10.3f' % 3.1415926) # 总宽度为10,小数点后3位: 3.142
print('{0}'.format(3.1415926)) # 3.1415926
print('{0:.3}'.format(3.1415926)) # .3表示三位数:3.14
print('{0:.3f}'.format(3.1415926)) # .3f表示三位小数:3.142
print('{0:10.3f}'.format(3.1415926)) # 总宽度为10,小数点后3位: 3.142
编码转换
编码:将字符串转换为二进制数据(bytes) encode()方法
解码:将二进制数据转换为字符串 decode()方法
s = '天涯共此时'
# GBK编码:一个中文占两个字节
print(s.encode(encoding='GBK')) # b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1'
# UTF-8编码:一个中文占三个字节
print(s.encode(encoding='UTF-8')) # b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'
byte = s.encode(encoding='GBK')
print(byte.decode(encoding='GBK')) # 天涯共此时
byte2 = s.encode(encoding='UTF-8')
print(byte2.decode(encoding='UTF-8')) # 天涯共此时
函数
创建和调用
def 函数名 (输入参数): 函数体 返回参数
def cal(a, b): # 形参:函数定义处
c = a + b
return c
参数调用
# 位置实参:根据形参对应位置进行传递
res = cal(10, 20) # 实参:函数调用处
print(res) # 30
# 关键字参数:根据形参名称进行传递
res = cal(b=20, a=10) # 形参名称=实参值
print(res) # 30
参数传递
不可变对象:在函数体的修改不会改变实参的值
可变对象:在函数体的修改会影响到实参的值
def fun(arg1, arg2):
print(arg1)
print(arg2)
arg1 = 100
arg2.append(100)
print(arg1) # 100
print(arg2) # [10, 20, 30, 100]
n1 = 11
n2 = [10, 20, 30]
fun(n1, n2)
print(n1) # 11
print(n2) # [10, 20, 30, 100]
返回值
返回多个值-------结果为元组
def fun(list1):
odd = []
even = []
for i in list1:
if i % 2 == 0:
odd.append(i)
else:
even.append(i)
return odd, even
list1 = [10, 29, 40, 56, 55]
t = fun(list1)
print(t, type(t)) # ([10, 40, 56], [29, 55]) <class 'tuple'>
返回一个值------结果为原类型
参数定义
函数定义默认值形参:若给形参设置默认值,则只有当实参传递不同时才更改形参值。
def fun(a, b=50):
print(a, b)
fun(100) # 100 50
fun(10, 20) # 10 20
print()函数:end=’\t’:修改了默认值参数,一行输出
print('hello', end='\t')
print('python') # hello python
可变的位置参数:无法事先确定传递的位置实参个数,* 定义可变位置形参,结果为一个元组,只能定义一个可变的位置参数。
def fun(*args):
print(args)
print(args[0])
fun(10) # (10,) 10
fun(10, 20, 30) # (10, 20, 30) 10
可变的关键字参数:无法实现确定传递的关键字实参个数,* 定义可变关键字形参,结果为一个字典,只能定义一个可变的关键字参数。
def fun(**args):
print(args)
fun(a=10) # {'a': 10}
fun(a=10, b=20, c=30) # {'a': 10, 'b': 20, 'c': 30}
共同使用:* 必须在 ** 前面
def fun2(*args1, **args2):
print(args1,args2)
fun2(10, 20, a=40, b=30) # (10, 20) {'a': 40, 'b': 30}
def fun3(**args1, *args2):
# 错误
参数总结:
实参
将序列中的每个元素都转换为位置实参:*
def fun(a, b, c): # a,b,c:形式参数
print('a=', a, 'b=', b, 'c=', c)
fun(4, 5, 6) # 4,5,6:位置实参
list1 = [1, 2, 3]
# *list1:将列表中的每个元素转换为位置实参传递
fun(*list1) # a= 1 b= 2 c= 3
将序列中的每个键值对都转换为关键字实参:**
dic1 = {'a': 11, 'b': 22, 'c': 33}
# **dic1:将字典中的每个键值对转换为关键字实参传递
fun(**dic1) # a= 11 b= 22 c= 33
形参
默认值形参:
# b是默认值形参
def fun(a, b=10):
print('a=', a, 'b=', b)
个数可变的位置形参:
def fun2(*args):
print(args)
个数可变的关键字形参:
def fun3(**args):
print(args)
*后只能用关键字传递:
def fun4(a, *, b, c):
print('a=', a, 'b=', b, 'c=', c)
# 位置+关键字实参传递
fun4(10, b=20, c=30)
形参顺序:
def fun5(a,b,*,c,d,**args):
pass
def fun6(a,b=10,*args,**args2):
pass
变量的作用域
全局变量:函数体外进行定义
局部变量:函数体内进行定义,若在函数体内部将局部变量用global声明,则可全局使用。
递归函数
组成部分:递归调用、递归终止条件
调用过程:分配栈帧、释放空间
等价于if … else:什么条件下终止,什么条件下调用
递归实现阶乘
def fac(n):
if n == 1:
return 1
else:
res = n*fac(n-1)
return res
递归求解斐波那契数列
def fac(n):
if n == 1 or n == 2:
return 1
else:
return fac(n-1) + fac(n-2)
# 输出前六项
for i in range(1, 7):
print(fac(i))
Bug与Debug
常见bug
- TypeError: ‘>=’ not supported between instances of ‘str’ and ‘int’
age = input('请输入年龄:')
if age >= 18:
print('Yes')
将input输入的str转换为int型
age = int(input('请输入年龄:'))
if age >= 18:
print('Yes')
- NameError: name ‘i’ is not defined
while i <10:
print(i)
定义循环体变量、改变while循环体变量
i = 0
while i <10:
print(i)
i += 1
- TypeError: can only concatenate str (not “int”) to str
print('python'+18)
字符串拼接类型转换
print('python'+'18')
- IndexError: list index out of range
list1 = [1, 2, 3]
print(list1[3])
索引越界 修改索引
list1 = [1, 2, 3]
print(list1[2])
异常处理机制
try…except
try块中抛出异常,则执行except块
try:
n1 = int(input('请输入一个整数:'))
n2 = int(input('请输入另一个整数:'))
res = n1/n2
print('结果为:', res)
except ZeroDivisionError:
print('除数不能为0')
except ValueError:
print('只能输入数字串')
print('程序结束')
try…except…else
try块中抛出异常,则执行except块,错误类型在e中;没有异常,则执行else
try:
n1 = int(input('请输入一个整数:'))
n2 = int(input('请输入另一个整数:'))
res = n1/n2
except BaseException as e:
print('出错了', e)
else:
print(res)
try…except…else…finally
finally块无论try块是否抛出异常,都会执行
try:
n1 = int(input('请输入一个整数:'))
n2 = int(input('请输入另一个整数:'))
res = n1/n2
except BaseException as e:
print('出错了', e)
else:
print(res)
finally:
print('谢谢您的使用')
输出
请输入一个整数:10
请输入另一个整数:20
0.5
谢谢您的使用
常见异常类型
ZeroDiversionError:数学运算异常:10 / 0
IndexError:索引异常:列表索引越界
KeyError:映射中没有该键:字典中没有该键
NameError:未声明/初始化对象
Invalid syntax:语法错误
ValueError:参数传入无效
traceback模块
打印异常信息
错误的log日志
import traceback
try:
print('-------------')
print(1/0)
except:
print(traceback.print_exc())
输出
Traceback (most recent call last):
File "C:/Users/dell/PycharmProjects/python_learning/main.py", line 649, in <module>
print(1/0)
ZeroDivisionError: division by zero
-------------
None
系列文章:
Python Learning Journal:Day1
Python Learning Journal:Day2
参考教程:入门到精通(Python全栈开发教程)