面向过程
Python简介
Python和Java的解释方式对比
Java:源代码 -> 编译成class -> Jvm解释运行
Python:源代码 -> Python解释器解释运行
我经常和身边的Java开发者开玩笑说:“Java真变态,别的语言都是要么直接编译要么直接解释,Java太另类了又编译又解释的......”
直接解释和编译后解释其实最大的区别就是源代码的安全性。
如果是直接解释源代码,那么源代码没有安全性可言,也就是任何一个人都可以打开源代码一看究竟,任何人都可以随意修改源代码。
事实上,Python和Java的解释方式是相同的,只是我们表面上看Python是直接解释源代码,而实际上python解释器只会加载字节码。细心的小伙伴肯定发现了这一点,当我们import某个模块时,总是会在模块所在的目录创建一个pycache目录,里面存放着被加载模块的字节码文件。
编译源代码有以下作用:
源代码保护(算法保护)/ 防止用户篡改源代码解释器加载代码速度加快
安装好py之后会有几个文件,如下:
IDLE:是py自带的一种简单的开发环境
Python+版本号:这个是python的交互式命令行程序
Python+版本号+ Manuals是官方技术文档(API)
Python+版本号+Module Docs是已安装模块的文档
Python输出
open('可以指定文件,将数据输出到对应文件中',a+"),a是以读写的方式创建,如果文件不存在的话就创建,存在的话就在文件后面追加
fp=open('D:/text.txt','a+')
print('helloworld',file=fp)
fp.close
转移字符
什么是转义字符?
就是反斜杠+想要实现转移功能的首字母
当字符串中包含反斜杠、单引号和双引号等有特殊用途的字符时,必须使用反斜杠对这些字符进行转移
反斜杠:\ \ 这里都用空格隔开了,不然中间会转移
单引号:\ ' (可以适用于单引号里面加单引号)
双引号: \ "
换行:\n
回车:\r
退一个格:\b 'hello\bworld' 输出hellworld
水平制表符:\t,一个制表符占位置4个字符,hello\t这样占3个,因为hell算1个制表符,0算一个,剩下3个字符算一个制表符
退格:\b
原字符:不希望字符串中的转义字符起作用,就用元字符,就是在字符串前面加上r或R,如:print(r'hello\nworld') 中间不能有空格,否则报错
注意:最后一个字符不能写一个反斜线 \ ,能写两个
print(r'helloWorld\' ) 错误,这里为了demo,写了两个\才显示一个\
Python基本类型
关键字
importkeyword pring(keyword.kwlist)
变量的定义
name='哈哈哈哈哈' print('标识',id(name)) print('类型',type(name)) print('值',name)
输出:
标识 2717730201040 内存地址,可以用id()输出内存地址,也就是标识 类型 <class 'str'> 值 哈哈哈哈哈 十进制-->默认的进制 八进制-->以0b开头 二进制-->以0o开头、 十六进制-->0x开头
浮点数
进行浮点数计算的时候会因为二进制的底层问题导致不精确,我们要小心,不用深究
解决方案:
导入模块decimal #3.4000000000000004 print(1.2+2.2) #导入Decimal之后 输出3.4 fromdecimalimportDecimal print(1.2+2.2) #3.4
布尔型
true表示1 false表示0
字符串
单引号'',双引号" ",三引号''''' ''''',''' '''-无论单双都是String类型 #单双引号换行自动会加 \ 否则报错,三引号不用加,这是唯一区别 str1='哈哈' \ '哈哈哈' str2="哈哈" \ "哈哈" str3=""" 哈哈哈哈哈 """
数据类型转换
str():将其它数据类型转换为字符串 int():将其它数据类型转换为整数 文字类和小数类字符串-小数串是无法转换为字符串,无法转换为整数 浮点数转换为整数:抹零取整 float():将其他数据类型转换为浮点数 文字类无法转换为整数 整数类转成浮点数,末尾为.0
Python中的注释和输入
注释
在代码中代码的功能进行说明,提升代码的可读性
注释分为三种类型的注释
单行注释:以#开头,直到换行结束
多行注释:并没有单独的多行注释标准,将一到三引号之间的代码称为多行注释
'afd''' '''afd''' """agd""" "agd"""
中文编码声明注释,在文件的开头加上中文声明注释,用来指定文件的编码格式
如
#coding:gbk java中单行注释 为: // 多行注释为 /** **/
input
它的类型是一个String类型
可以将输出的内容直接转换
a=int(input(' 请输入一个加数')) present=input('随便输入') print(present,type(present))
输出
随便输入a
a <class 'str'>
运算符
//表示整除运算(11%2=5)
整除注意:一正一负向下取整(9//-4=-3)
2**2表示2的2次方
%:取模
一正一负的余数=被除数-除数*商
9%-4=9-(-4)*(-3)=-3
赋值运算符
从右到左执行
a,b,c=20,30,40分别给abc赋值 a=b=c=20表示 ab进行交换: a,b=b,a
比较运算符
一个=是赋值,==称为比较运算符,
比较对象用的是 is / is not说明它们的标识id是否相同
布尔运算符
and:两个都为true的时候,才为true
or:只有只有一个为true即为true
not:运算数为true,结果为false;运算为false,结果为true
in 和 not in str='helloworld' print('w' in str) #true print('w' not in str) #false print('z' in str) #false print('z' not in str) #true
位运算符
位与& : 对应数位都是1,结果才是1,否则为0(底层转换为二进制,每右边开始每一位进行比较) 4: 0 0 0 0 0 1 0 0 8: 0 0 0 0 1 0 0 0 结:0 0 0 0 0 0 0 0 位或|:对应数位都是0,结果数位才是0,否则为1 左移运算符 << :高位溢出舍弃,低位补0,向左移动一位,相当于乘以2 左移一位: 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 低位补0 右移运算符 >>:低位溢出舍弃,高位补0,相当于除以2 右移一位: 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 -->0 低位截断
对象的布尔值
print(bool(0.0))#false print(bool(None))#false print(bool(''))#false print(bool(""))#false print(bool([])) #空列表 print(bool(list())) #空列表 print(bool(()))#空元组 print(bool(tuple()))#空元组 print(bool({})) #空字典 print(bool(dict())#空字典 print(bool(set()))#空集合 print('以上布尔值全为false,其它对象的布尔值都为true')
分支结构
单分支结构
money=1000 minus=int(input("请输入金额")) if money>=minus: money-=minus print(money)
双分支结构
if 条件表达式: 条件执行体1 else: 条件执行体2
多分支结构
if 条件表达式1: 条件执行体1 elif 条件表达式2: 条件执行体2 elif 条件表达式N: [else:] #这个[]中的内容是可写可不写的,多分支else是可以省略的 条件执行体N+1
嵌套分支
if 条件表达式: if 条件表达式: elif 条件表达式 else: else: if 条件表达式: else:
条件表达式
num_a=int(input("请输入第一个整数:")) num_b=int(input("请输入第二个整数:")) print(str(num_a),'大于等于',str(num_b) if (num_a>=num_b) else str(num_a)+"小于"+str(num_b)) #这里注意,整数和字符串想加是出错的, #这里注意,整数和字符串想加是出错的,需要转换才能进行--java这里可以自动识别相加,python不行 输出 请输入第一个整数:3 请输入第二个整数:1 3 大于等于 1
pass语句
pass语句什么都不做,只是一个占位符,用在语法上需要占位的地方
什么时候用?
先搭建语法结构,没想好代码怎么写的时候,写pass语法不报错
哪些语句一起使用
if语句的条件执行体
for-in语句的循环体
定义函数时的函数体
if answer='y': pass else: pass
内置函数range()
range()函数
用于生成一个整数序列
创建range对象的三种方式
range(stop)->创建一个[0,stop]之间的整数序列,步长为1 range(start,stop)->创建一个[start,stop)之间的整数序列,步长为1 range(start,stop,step)->创建一个[start,stop)之间的整数序列,步长为step
返回值是一个迭代器对象
range类型的优点:不管range对象表示的整数序列有多长,所有range对象占用的内存空间都是相同的,因为仅仅需要存储start,stop和step,只有当用到range对象时,才会去计算序列中的相关元素
in与not in判断整数序列中是否存在(不存在)指定的整数
#第一种创建方式 r=range(10) #[0,1,2,3,4,5,6,7,8,9],默认从0开始,默认相差1为步长 print(r)#range(0,10) print(list(r))#用于查看range对象中的整数序列 -->list是列表的意思 #第二种创建方式 # [1, 2, 3, 4, 5, 6, 7, 8, 9] r=range(1,10) print(list(r)) #第三种创建方式 #[1, 3, 5, 7, 9] r=range(1,10,2) print(list(r)) print(10 in r) # false print(10 not in r)# true
循环结构
循环的分类
while
for -in
语法结构
while 条件表达式
条件执行体(循环体)
if是判断一次,条件为True执行一次
while是判断N+1次,条件为True执行N次
for-in循环
in表达从(字符串、序列等)中依次取出,又称遍历
for-in遍历的对象必须是可迭代对象
for-in的语法结构
for 自定义的变量 in 可迭代对象
循环体
循环体内不需要访问自定义变量,可以将自定义变量替代为下划线
for item in 'Python': print(item) # 分别打印Python的各个字母 for i in range(10): print(i) # 打印1-9的数字 #如果在循环体中不需要使用自定义变量,可以将其设置为_,以下打印5次 for _ in range(5): print('人生苦短,我用python') sum = 0 #用于存储偶数和 for item in range(1,100): if item%2 == 0: sum += item print('1-100之间的偶数和为:',sum) 水仙花数 for item in range(100,1000): single = item % 10 ten = item // 10 % 10 hundred = item // 100 if(hundred**3+ten**3+single**3==item): print(item) java的这样输入 //如153-java有明确的类型标注,不用和py一样//取整 int x = a/100;//结果取整 分解出百位数 1 int y = a/10%10;//分解出十位数 5 int z = a%10;//个位数 3 输出 153 370 371 407
流程控制语句
break 经常和if一起用 for item in range(3): pwd = input('请输入密码:') if pwd == '888': print("success") break #执行成功跳出for循环 else: print('fail') continue 用于结束当前循环,进入下一次循环,通常和if一起使用
else语句
与else语句配合使用的三种情况
if...else: if条件不成立时执行else
while...else: 没有碰到break时执行else
for...else: 没有碰到break时执行else
while...else a = 0 while a < 3: pwd=input('please input your password:') if pwd == '123': print('密码正确') break else: print('密码错误') else: print('sorry,三次均输入错误') 打印矩形 for i in range(1,4): for j in range(1,5): print("*",end = '\t') #不换行输出 print() * * * * * * * * * * * * 九九乘法表 for i in range(1,10): # 9行,不包括10 for j in range (1,10): if(j<=i): print(str(j)+' * '+str(i)+' = '+str(j*i),end='\t') print()
输出
1 * 1 = 1 1 * 2 = 2 2 * 2 = 4 1 * 3 = 3 2 * 3 = 6 3 * 3 = 9 1 * 4 = 4 2 * 4 = 8 3 * 4 = 12 4 * 4 = 16 1 * 5 = 5 2 * 5 = 10 3 * 5 = 15 4 * 5 = 20 5 * 5 = 25 1 * 6 = 6 2 * 6 = 12 3 * 6 = 18 4 * 6 = 24 5 * 6 = 30 6 * 6 = 36 1 * 7 = 7 2 * 7 = 14 3 * 7 = 21 4 * 7 = 28 5 * 7 = 35 6 * 7 = 42 7 * 7 = 49 1 * 8 = 8 2 * 8 = 16 3 * 8 = 24 4 * 8 = 32 5 * 8 = 40 6 * 8 = 48 7 * 8 = 56 8 * 8 = 64 1 * 9 = 9 2 * 9 = 18 3 * 9 = 27 4 * 9 = 36 5 * 9 = 45 6 * 9 = 54 7 * 9 = 63 8 * 9 = 72 9 * 9 = 81
拓展:
python里的end是print函数中的参数,为末尾end传递一个字符串,这样print函数不会在字符串末尾添加一个换行符,而是添加一个字符串,其实这也是一个语法要求,表示这个语句没结束。
二重循环中的break和continue
二重循环中的break和continue用于控制本层循环
continue:
跳过本次循环体中剩下尚未执行的语句,立即进行下一次的本循环条件判定,可以理解为只是中止(跳过)本次循环,接着开始下一次本循环的条件语句
break:
如果有两层for循环,第二层循环中有if...break,跳出的是第二层for循环,继续执行第一层的下一个条件语句
列表
为什么需要列表
变量可以存储一个元素,而列表是一个大容器,可以存储N多个元素,程序可以方便地对这些数据进行整体操作
列表相当于其它语言中的数组
变量存储的是一个对象的引用,而列表存储的是多个对象的引用
列表的创建用 [] 或者内置函数list()创建
元素之间用,分割
列表元素按顺序有序培训
索引映射唯一一个数据
列表可以存储重复元素
任意类型混存
根据需要动态分配和回收内存
和java不同的是:从后往前采用的是负数索引比如第一个0的索引,它同时也是负数最后一个索引,java索引从0开始,无负数
如果列表中有多个元素,只返回列表中相同元素第一个元素的索引
在指定索引进行查找
lst=['hello','world','99','hello'] print(lst.index('hello',1,3)) #1-3不包括3,这里会报错找不到索引
获取列表中的多个元素
语法格式
列表名[start : stop : step]
切片的结果:原列表片段的拷贝
切片的范围,[start,stop)
step默认为1,简写为[stop,step]
lst=[10,20,30,40,50,60,70,80] print('原列表',id(lst))# 原列表 3184358125248 lst2=lst[1:6:1] print('切的片段:',id(lst2))# 切的片段: 3184361791744 print(lst[1:6]) # 默认步长为1 [20, 30, 40, 50, 60] print(lst[1:6:])# [20, 30, 40, 50, 60] print(lst[1:6:2]) # [20, 40, 60] print(lst[:6:2]) # [10, 30, 50] print(lst[1::2]) # [20, 40, 60, 80] print('----------step步长为负数的情况-----------------') print(lst[::-1]) # [80, 70, 60, 50, 40, 30, 20, 10] 相当于start=7最后一个元素 print(lst[6:0:-2])# [70, 50, 30]
列表元素的判断及遍历
for 迭代变量 in 列表名:
操作
print(10 in lst) #True print(10 not in lst) #False
遍历
for item in lst: print(item)
列表元素的增删改操作
增加
append():在列表的末尾添加一个元素
extend():在列表的末尾至少添加一个元素
insert():在列表的任意位置添加一个元素
切片:在列表的任意位置添加至少一个元素
id没变说明,append是在同一个列表中添加元素,每一个元素的id不同,但这个列表的id不变
lst=[10,20,30]
print('添加元素之前',lst,id(lst)) #添加元素之前 [10, 20, 30] 1732983054336
lst.append(40)
print('添加元素之后',lst,id(lst)) #添加元素之后 [10, 20, 30, 40] 1732983054336
添加列表
将lst2作为一个元素添加到lst1的末尾
lst2=['hello','world'] lst.append(lst2) print(lst) #[10, 20, 30, 40, ['hello', 'world']] 用extend()添加列表 lst2=['hello','world'] lst.extend(lst2) print(lst) # [10, 20, 30, 40, 'hello', 'world']
在任意位置上添加一个元素
lst = [10,20,30] lst.insert(1,90) print(lst) #[10, 90, 20, 30, 40]
切片
lst.insert(1,90) print(lst) # [10, 20, 30, 40] lst3=[True,False,'hello'] # [10, 90, 20, 30, 40] lst[1:]=lst3 print(lst) # [10, True, False, 'hello']
列表元素的删除操作
remove():一次删除一个元素
重复元素只删除第一个
元素不存在抛出ValueError
pop() :删除一个指定索引位置上的元素
指定索引不存在抛出IndexError
不指定索引,删除列表中最后一个元素
切片:一次至少删除一个元素
clear():清空列表
del:删除列表
lst=[10,40,50,60] new_list=lst[1:3] print('原列表:',lst) # 原列表: [10, 40, 50, 60] print('切片后的列表:',new_list) # 切片后的列表: [40, 50]
#不产生原列表中的对象,而是删除原列表中的内容 lst[1:3]=[] print(lst) # [10, 60] del lst print(lst) # name 'lst' is not defined 既然删除了,那么就没有定义
列表元素的排序操作
常见的两种方式:
调用sort()方法,列表中所有元素默认按照从大到小顺序进行排序,指定reverse=True,进行降序排序,默认是False
调用内置函数sorted(),可以指定reverse=True,进行降序排序,原列表不发生改变,id不会变
sort()是对原列表进行排序,sorted()是对新列表进行排序
列表生成式
列表生成式简称 生成列表的公式
语法格式:[ i * i for i in range(1,10) ]
i * i 表示列表元素的表达式,自定义, for后面的 i 表示自定义变量,range(1,10)表示可迭代对象
lst=[i for i in range(1,10)] #会产生一个1-9的整数序列,所以用[]括起来,这个列表中存的是产生的整数序列,产生的整数序列是i,所以在for之前加上i
print(lst) #[1, 2, 3, 4, 5, 6, 7, 8, 9]
字典
字典是Python内置的数据结构之一<class 'dict'>,与列表一样是一个可变的序列(进行增删改)
以键值对的方式存储数据,字典是一个无序的序列
第一个放进去不一定在第一个位置(它底层会用hash计算键进行放入)
字典会浪费较大的内存,是一种空间换时间的数据结构
无序不可重复
字典中的可以是不可变对象
scores={'张三': 100, '李四' : '98'}
根据key找value
类似于java中的Map,也都是无序不可重复 ,重复即覆盖
字典的创建
最常用的方式:使用花括号
scores={' 张三' : 100, '李四' : 98}
使用内置函数dict()
dict(name = 'jack' , age= 20)
取值与使用get()取值的区别
[]如果字典中不存在指定的key,抛出keyError异常
get()方法取值,如果字典中不存在指定的key,并不会抛出KeyError,而是返回None,可以通过参数设置默认的value,以便指定的key不存在时返回
scores={'张三': 100, '李四' : '98'} scores.get('哈哈',99) #99是在查找哈哈不存在时候返回99
key的判断
in :指定的key在字典中存在返回True
not in:指定的key在字典中不存在时返回True
字典的删除:del scores['张三']
字典的新增:scores['jack']=90 没有则新增,有则value覆盖
字典的清空:clear
获取字典视图的三个方法
获取字典视图
keys():获取字典中所有key,类型<class 'dict_keys'>
也可以将其转换为列表,list(keys)
values():获取字典中所有value,类型<class 'dict_values'>
items():获取字典中所有的key,value对
scores={'张三':100,'李四':98,'王五':45}
# 获取所有的key keys = scores.keys() print(keys) # dict_keys(['张三', '李四', '王五']) print(type(keys)) # <class 'dict_keys'> print(list(keys)) # ['张三', '李四', '王五'] # 获取所有value values=scores.values() print(values) # dict_values([100, 98, 45]) print(type(values)) # <class 'dict_values'> print(list(values)) # [100, 98, 45] # 获取所有的key-value对 items=scores.items() print(items) # dict_items([('张三', 100), ('李四', 98), ('王五', 45)]) print(list(items)) # 这个小括号称为元祖[('张三', 100), ('李四', 98), ('王五', 45)]
字典元素的遍历
scores={'张三':100,'李四':98,'王五':45} for item in scores: print(item,scores[item],scores.get(item)) # scpres.get()和scores[]都是根据key获取value 输出 张三 100 100 李四 98 98 王五 45 45
字典生成式
内置函数zip()
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元祖,然后返回由这些元组组成的列表
items=['Fruits','Books','Others'] prices=[96,78,85] d = {item : price for item,price in zip(items , prices)} print(d) # {'Fruits': 96, 'Books': 78, 'Others': 85} # d = {item.upper() : price for item,price in zip(items , prices)} item.upper()会全部变成大写
元组
python内置数据结构之一,是一个不可变序列
不可变序列与可变序列
不可变序列
字符串、元组
没有增删改操作
字符串、元组
增删改内存地址发生改变
java中的String同样也是不可变序列
private final char value[]; // 不可变指的是内存地址不能修改
可变序列
列表、字典
可以增删改,对象地址不发生改变
<class 'tuple'>
创建方式
直接小括号t = ('Python' , 'hello')
也可以省略小括号:t = ‘Python’ , 'hello'
使用内置函数tuple()
t = tuple( ('Python' , 'hello') ) 注意:只包含一个元组的元素需要使用逗号 t = (10 , ) 否则会被当成字符串!
空列表创建:
lst = [] lst1 = list ()
空字典:
d = {} d2 = dict ()
空元组:
t4 = () t5 = tuple()
lst = [] lst2 = list() d = {} d2 = dict() t = () t2 = tuple() print('空列表', lst ,lst2) print('空字典', d,d2) print('空元组' , t, t2) 输出 空列表 [] [] 空字典 {} {} 空元组 () ()
注意:
元组中存储的是对象的引用
如果元组中对象本身是不可变对象,则不能再引用其它对象
如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变
t = (10 ,[20,30],9) print(t) print(type(t)) # [20, 30] print(t[1]) # 元组是不能再修改新的地址 t[1].append(100) #列表是可变序列,是可以添加元素的,但是id是不变的
元组的遍历
元组是可迭代对象,所以可以用for in 遍历
t = (10 ,[20,30],9) for item in t: print(item)
集合
Python提供的内置数据结构
与列表、字典一样都属于可变类型的序列
集合{key}是没有value的字典-{key : value}
不能重复,重复即覆盖
通过hash(dataA)哈希进行计算,第一个放未必在第一个位置
创建方式
直接{} ,和字典区别就是没有value
使用内置函数set()
集合的相关操作
in 或者 not in
调用add()方法,一次添加一个元素
调用update()方法至少添加一个元素 ,里面可以添加集合,可以添加列表,元组等
集合元素的删除操作
调用remove()方法,一次删除一个指定元素,如果指定元素不存在,抛出,KeyError
调用discard()方法,一次删除一个指定元素,如果指定元素不存在不抛异常
调用pop()方法,一次只删除一个任意元素,它是随机删除的
调用clear()方法,清空集合
集合之间的关系
两个集合是否相等
可以使用运算符==或!=进行判断
一个集合是否是另一个集合的子集
可以调用方法issubset进行判断
B是A的子集
一个集合是否是另一个集合的超集
可以调用方法issuperset进行判断
A是B的子集
两个集合是否没有子集
可以调用方法isdisjoint进行判断 (disjoin-adj不相交的,v拆散)
s = {10,20} s2 = {20,10} s3 = {10} print(s==s2) #True print(s.issubset(s2)) # True print(s2.issubset(s)) # True print(s.issubset(s3)) # False print(s.issuperset(s3)) # True print(s3.isdisjoint(s)) # Falsexxxxxxxxxx s = {10,20}s2 = {20,10}s3 = {10}print(s==s2) #Trueprint(s.issubset(s2)) # Trueprint(s2.issubset(s)) # Trueprint(s.issubset(s3)) # Falseprint(s.issuperset(s3)) # Trueprint(s3.isdisjoint(s)) # Falses = {10,20}s2 = {20,10}print(s==s2) #True
集合的数学操作
交集:A和B共有的
并集:A和B所有元素加一起的
差集:s1.difference(s2):是求集合s1和s2的差集,即求在s1中同时不在s2中的元素集合,该方法的返回值是二者差集。
对称差集:s1.symmetric_difference(s2):是求集合s1和s2的对称差集,即s1和s2的并集减去二者的交集,该方法的返回值是二者的对称差集。
集合生成式
也就是用于生成集合的公式
{i * i for i in range(1,10)}
将{}改为[] 就是列表生成式
没有元组生成式-不可变序列
列表、字典、元组、集合总结
字符串的创建和驻留机制
在Python中字符串是基本数据类型 ,java中String是引用数据类型
什么是字符串驻留机制
仅保存一份相同且不可变字符串的方法,不同的值,被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量(不会创建新的空间,而是指向已经创建的空间)
a = 'Python'
b = "Python"
c = '''Python'''
print(a,id(a)) # Python 1365644283120
print(b,id(b)) # Python 1365644283120
print(c,id(c)) # Python 1365644283120
Java和Python中等于的区别
Python中is用于判断两个变量引用对象是否为同一个,==用于判断引用变量的值是否相等
Java只有值传递,所以对于==来说,不管是比较基本数据类型,还是引用数据类型的变量,其本质比较的都是值,只是引用类型变量存的值是对象的地址。
java中的equals()方法:用来比较两个对象的内容是否相等
public boolean equals(Object obj) {
return (this == obj);
字符串的驻留机制
驻留机制的几种情况(交互模式-命令窗口)
字符串的长度为0或1时,无论是标识符与否都驻留
符合标识符的字符串
字符串只在编译时驻留,而非运行时
[-5,256]之间的整数数字
s = '' s1 = '' print(s is s1) # True s2 = '%' s3 = '%' print(s2 is s3) # True print(a==b) # True a='Python' print(a is b) # True b="Python" d = 'abc%' # 非标识符 标识符字母数字下划线 e = 'abc%' print(d==e) # True print(d is e) # False 在PyCharm中运行时True,要在交互模式 a = 'abc' b = 'ab' + 'c' # b的值是在运行之前就已经连接完毕了 c = ''.join(['ab','c']) # c是在程序运行的时候通过join方法连接的,会开辟新的空间,没有驻留 print(type(a)) # <class 'str'> print(type(b)) # <class 'str'> print(type(c)) # <class 'str'> print(a is b) # True print(a is c) # False # [-5 - 256]之间的数字也是驻留的 a = -5 b = -5 print(a is b) # True a = -6 b = -6 print(a is b) # False # 感觉两个内存地址,这样太浪费空间了,所以我们可以让它存储一个空间 a = 'abc%' b = 'abc%' print(a is b) # False import sys sys.intern(a) print(a is b) # True
PyCharm对字符串进行了优化,原本不驻留的,PyCharm进行了驻留
驻留机制的优缺点
当需要值相同的字符串时,可以直接从字符串池中来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是会比较影响性能的
在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()方式是先计算出所有字符串的长度,然后再拷贝,只new一次,效率比+效率高
由于字符串是不可变对象,当使用“+”连接字符串的时候,每执行一次“+”操作都会申请一块新的内存,然后复制上一个“+”操作的结果和本次操作的有操作符到这块内存空间中,所以用“+”连接字符串的时候会涉及内存申请和复制;join在连接字符串的时候,首先计算需要多大的内存存放结果,然后一次性申请所需内存并将字符串复制过去。在用"+"连接字符串时,结果会生成新的对象,而用join时只是将原列表中的元素拼接起来,因此在连接字符串数组的时候会考虑优先使用join。
字符串的常用操作
字符串的查询操作的方法
index():查找子串substr第一次出现的位置,如果查找的字符串不存在,抛出ValueError
rindex():查找子串substr最后一次出现的位置,如果查找的子串不存在,抛出ValueError
find():查找子串substr第一次出现的位置,不存在返回-1
rfind():查找子串substr最后一次出现的位置,如果查找的子串不存在,返回-1
r:reserve v.n.adj都表示相反的、逆转、背面的意思,
建议用find方法,不跑异常
字符串的大小写转换操作的方法
upper(): 把字符串所有字符都转成大写字母
lower():把字符串中所有字符都转成小写字母
swapcase():大小写转换,大写变小写,小写变大写
capitalize():把第一个字符转换为大写,其余转小写
title,第一个转大写,每个单词首字母大写,其余小写
字符串内容对齐操作的方法
center():居中对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置的宽度小于实际宽度则返回源字符串
ljust():左对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置的宽度小于实际宽度则返回源字符串
rjust():右对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置的宽度小于实际宽度则返回源字符串
zfill():右对齐,左边用0填充,该方法只接受一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串的长度,返回字符串本身
s = 'hello,Python' print(s.center(20,'*')) # ****hello,Python**** # 共指定20个字符,减去原有12个居中对齐,左右补充 * print(s.ljust(20,'*')) # hello,Python******** print(s.rjust(20,'*')) # ********hello,Python print(s.zfill(20)) # 00000000hello,Python print('-666888'.zfill(8)) # -0666888
字符串的劈分
split():从字符串左边开始劈分,默认的劈分字符是空格字符串,返回值的值是一个列表
以通过参数sep指定劈分字符串是的劈分符
通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的子串会单独作为一部分、
rsplit():从字符串的右边开始劈分,默认的劈分字符是空格字符串,返回的值是一个列表
以通过参数sep指定劈分字符串是的劈分符
通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大劈分之后,剩余的子串会单独作为一部分
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'] # rsplit同理
判断字符串操作的方法
isidentifier():判断指定的字符串是不是合法的标识符
isspace():判断指定的字符串是否全部由空白字符组成(回车、换行、水平制表符)
isalpha():判断指定字符是否全部由字母组成,汉字也算(unicode编码就会这样)
isdecimal():判断指定字符是否全部由十进制的数字组成
isnumeric():判断指定的字符串是否全部由数字组成
isalnum():判断指定字符串是否全部由字母和数字组成
s = 'hello,Python' print('1.',s.isidentifier()) # False 有, 只要非数字字母下划线都非标识符 print('2.','hello_123'.isidentifier()) # True print('3.','\t'.isspace()) # True print('4.','abc'.isalpha()) # True print('5.','张三'.isalpha()) # True print('6.','张三1'.isalpha()) # False print('7.','123四'.isdecimal()) # False print('8','123'.isnumeric()) # True print('9','123哈哈哈'.isalnum()) # True
字符串操作的其它方法
字符串替换
replace() 第一个参数指定被替换的子串,第二个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,调用该方法时可通过第三个参数指定最大替换次
字符串的合并
join() 将字符串合并成一个字符串,如果是字典,则只连接key
注意:如果有数字什么的不能连接,只能连接字符串
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 print('|'.join(lst)) # hello|Java|Python print(''.join(lst)) # helloJavaPython t = ('hello','Java') print(''.join(t)) # helloJava
字符串的比较操作
运算符:>,>=,<,<=,==,!=
比较规则:从第一个字符依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续将不再比较
比较原理:比较的是ordinal value(原始值),调用内置函数ord可以,得到指定字符的ordinal value ,与内置函数ord对应的是内置函数chr,调用内置函数chr时可以指定oridnal value可以得到对应的字符
字符串的切片操作
字符串是不可变类型
不具备增、删、改等操作
切片操作都将产生新的对象,和列[]列表一样
[start,end,step]
s[:5]它会从0开始且,且到4,不包含5
s[6:]它会从6开始,切刀最后
s = 'hello,Java' s1 = s[:5] print(s1) s2 = s[6:] # hello print(s2) # Java a = '666888' print(a[::2]) #668