Python学习
python列表
列表是一个‘大容器’,可以存放多个元素,列表的使用:
list1 = ['hello', 'world', 98]
print(id(list1)) # 2726854589056
print(type(list1)) # <class 'list'>
print(list1) # ['hello', 'world', 98]
列表存放元素示意图:
创建列表的方式:
- 使用方括号
- 使用内置函数list()
list1 = ['hello', 'world', 98]
print(id(list1)) # 2726854589056
print(type(list1)) # <class 'list'>
print(list1) # ['hello', 'world', 98]
list2 = list(['hello', 'world', 98])
print(id(list2)) # 2013235899136
print(type(list2)) # <class 'list'>
print(list2) # ['hello', 'world', 98]
列表的特点:
- 列表元素按顺序有序排序
- 索引映射唯一数据
- 列表可以存储重复数据
- 任意数据类型混存
- 根据需要动态分配和回收内存
list1 = ['hello', 'world', 98, 97, 'hello']
# 利用索引取列表中的元素 从前往后是非负数,从后往前是负数
print(list1[1], list1[-4])
列表的查询操作
- 获取列表中指定元素的索引
# 如果查询的元素在列表中不存在,则会抛出ValueError
list2 = list(['hello', 'world', 98, 'hello'])
# 如查列表中存在N个相同元素,只返回相同元素中的第一个元素的索引
print(list2.index('hello')) # 0
# 还可以在指定的start和stop之间进行查找
print(list2.index('world', 1, 3))
- 获取列表中的单个元素
list1 = ['hello', 'world', 98, 97, 'hello']
# 正向索引从0到N-1
print(list1[1]) # world
# 逆向索引从-N到-1
print(list1[-2]) # 97
-
获取列表中的多个元素 : 切片操作
- 语法格式: 列表名[start : end : step]
- 切片结果:原列表的子集
- 切片的范围:[start, end)
- step默认为1
- step为正数,从start往后开始计算切片;[start :: step],从start开始,到最后一个元素,步长为step;[: end : step],从第一个元素开始,到end结束,但是不包括end,步长为step
- step为负数,从start往前开始计算切片;[start :: step],从start开始,到第一个元素,步长为step;[: end : step],从最后一个元素开始,到end结束,但是不包括end,步长为step
list1 = [10, 20, 30, 40, 50, 60, 70] print(list1[1:5:1]) # [20, 30, 40, 50] print(list1[::2]) # [10, 30, 50, 70] print(list1[:5:2]) # [10, 30, 50] print(list1[:5:-2]) # [70] print(list1[1::-2]) # [20]
-
判断指定元素是否在列表中存在
list1 = ['hello', 'world', 98, 97, 'hello']
print('world' in list1) # True
print(20 in list1) # False
- 列表元素的遍历
for item in list1:
print(item)
列表的增加操作
append()
在列表的末尾添加一个元素
list1 = ['hello', 'world', 98, 97, 'hello']
list1.append(100)
print(list1) # ['hello', 'world', 98, 97, 'hello', 100]
list2 = [10,20]
list1.append(list2)
print(list1) # ['hello', 'world', 98, 97, 'hello', 100, [10, 20]]
extend()
在列表的末尾至少添加一个元素
list1 = ['hello', 'world', 98, 97, 'hello']
list1.append(100)
print(list1) # ['hello', 'world', 98, 97, 'hello', 100]
list2 = [10,20]
list1.extend(list2)
print(list1) # ['hello', 'world', 98, 97, 'hello', 100, 10, 20]
insert()
在列表的任意位置添加一个元素
list1 = ['hello', 'world', 98, 97, 'hello']
list1.insert(1,20)
print(list1) # ['hello', 20, 'world', 98, 97, 'hello']
在任意位置添加多个元素,实质上是先切片再替换,把切掉的部分换掉
list1 = ['hello', 'world', 98, 97, 'hello']
list2 = [10, 20]
list1[1:] = list2
print(list1) # ['hello', 10, 20]
列表的删除操作
remove()
- 一次只删除一个元素
- 重复元素只删除匹配到的第一个元素
- 删除的元素不存在报ValueError异常
list1 = ['hello', 'world', 98, 97, 98, 'hello']
list1.remove(98)
print(list1) # ['hello', 'world', 97, 98, 'hello']
pop()
- 删除指定索引位置上的一个元素
- 不指定索引,则默认删除列表最后一个元素
- 指定索引不存在抛出 IndexError 异常
list1 = ['hello', 'world', 98, 97, 98, 'hello']
list1.pop(1)
print(list1) # ['hello', 98, 97, 98, 'hello']
list1.pop()
print(list1) # ['hello', 98, 97, 98]
利用切片操作一次最少删除一个元素,实际上就是切片
list1 = ['hello', 'world', 98, 97, 98, 'hello']
list2 = list1[1:4]
print(list2) # ['world', 98, 97]
list1 = ['hello', 'world', 98, 97, 98, 'hello']
list1[1:4] = []
print(list1) # ['hello', 98, 'hello']
clear()
- 清空列表
list1 = ['hello', 'world', 98, 97, 98, 'hello']
list1.clear()
print(list1) # []
del()
- 删除列表
list1 = ['hello', 'world', 98, 97, 98, 'hello']
del list1
#print(list1) NameError: name 'list1' is not defined
列表的修改操作
- 为指定索引的元素赋予一个新的值
list1 = ['hello', 'world', 98, 97, 98, 'hello']
list1[2] = 20
print(list1) # ['hello', 'world', 20, 97, 98, 'hello']
- 为指定的切片赋予一个新的值
list1 = ['hello', 'world', 98, 97, 98, 'hello']
list1[1:3] = [100, 200, 300, 400]
print(list1) # ['hello', 100, 200, 300, 400, 97, 98, 'hello']
列表的排序操作
常见的两种方式:
- 调用sort() 方法,列表中的所有元素默认按照从小到大的方式进行排序,可以指定 reverse = True,进行降序排序,原列表发生改变,变化前后的列表所占的内存空间是一致的
list1 = ['hello', 'world', 'hello'] # 进行排序的列表必须是 同类型的 数据,可以都是 str 或 int
print("排序前的列表:\t", list1) # 排序前的列表: ['hello', 'world', 'hello']
print("排序后的列表:\t", list1.sort()) # 排序后的列表: None list1.sort()返回值为None
print("排序后的列表:\t", list1) # 排序后的列表: ['hello', 'hello', 'world']
list1.sort(reverse=True)
print("排序后的列表:\t", list1) # 排序后的列表: ['world', 'hello', 'hello']
- 调用内置函数 sorted() , 可以指定 reverse = True,进行降序排序,原列表不变
list1 = [10, 50, 30, 64]
print("排序前的列表:\t", list1) # 排序前的列表: [10, 50, 30, 64]
print("排序后的列表:\t", sorted(list1)) # 排序后的产生的新列表: [10, 30, 50, 64]
print("排序后的列表:\t", list1) # 排序后的列表list1: [10, 50, 30, 64]
list1.sort(reverse=True)
print("排序后的列表:\t", sorted(list1, reverse=True)) # 降序排序后的产生的新列表: [64, 50, 30, 10]
列表生成式
- 语法格式:
- [ 表示列表元素的表达式 for 自定义变量 in 可迭代对象]
- 如:[i * i for i in range(10)]
- 注意事项:“表示列表元素的表达式” 中应该包含 for循环中的自定义变量
- 注意加上 []
list1 = [item * item for item in range(10,20)]
print(list1) # [100, 121, 144, 169, 196, 225, 256, 289, 324, 361]
python字典
以键值对的方式存储数据,字典是一个无序的序列,即键值对放入的先后顺序跟存储位置的前后无关,键值对的存入位置是经过hash(key)算出来的,key也必须是不变的,可以使str类型,也可以是int类型
字典就是根据key找value的位置
字典的创建
- 使用 {}
dict1 = {'张三': 15, '李四': 25, '王五': 35}
print(dict1) # {'张三': 15, '李四': 25, '王五': 35}
print(type(dict1)) # <class 'dict'>
- 使用内置函数 dict()
# dict括号里面,等号左边为键,等号右边为值
dict1 = dict(name='wwj', age=20)
print(dict1) # {'name': 'wwj', 'age': 20}
- 创建空字典
dict1 = {}
print(dict1) # {}
字典元素的获取
- 通过 [] 获取,如 dict1[‘张三’]
- 通过 get() 获取,如dict1.get(‘张三’)
- 二者的区别:
- [] 取值如果字典中不存在指定的key,则会抛出keyError异常
- get() 取值如果字典中不存在指定的key,并不会抛出keyError异常,而是返回None,或者可以设置默认的Value,当指定的key不存在时返回
dict1 = {'张三': 15, '李四': 25, '王五': 35}
print(dict1['张三']) # 15
# print(dict1['wwj']) KeyError: 'wwj'
print(dict1.get('王五')) # 35
print(dict1.get('wwj')) # None
# 使用get获取字典中的元素时,设置key不存在的默认value
print(dict1.get('wwj',20)) # 20
判断key是否存在 dict 当中
- 使用 in 来判断
dict1 = {'张三': 15, '李四': 25, '王五': 35}
print('wwj' in dict1) # False
print('wwj' not in dict1) # True
字典元素的删除
- del()
dict1 = {'张三': 15, '李四': 25, '王五': 35}
del dict1['张三']
print(dict1) # {'李四': 25, '王五': 35}
字典的清空
- clear()
dict1 = {'张三': 15, '李四': 25, '王五': 35}
dict1.clear()
print(dict1) # {}
字典元素的新增
dict1 = {'张三': 15, '李四': 25, '王五': 35}
dict1['wwj'] = 20
print(dict1) # {'张三': 15, '李四': 25, '王五': 35, 'wwj': 20}
字典元素的修改
dict1 = {'张三': 15, '李四': 25, '王五': 35}
dict1['王五'] = 55
print(dict1) # {'张三': 15, '李四': 25, '王五': 55}
获取字典视图
- keys() 获取字典所有的key
- values() 获取字典所有的value
- items() 获取字典所有的键值对
dict1 = {'张三': 15, '李四': 25, '王五': 35}
keys1 = dict1.keys()
print(keys1) # dict_keys(['张三', '李四', '王五'])
print(type(keys1)) # <class 'dict_keys'>
print(list(keys1)) # ['张三', '李四', '王五']
values1 = dict1.values()
print(values1) # dict_values([15, 25, 35])
print(type(values1)) # <class 'dict_values'>
print(list(values1)) # [15, 25, 35]
items1 = dict1.items()
print(items1) # dict_items([('张三', 15), ('李四', 25), ('王五', 35)])
print(type(items1)) # <class 'dict_items'>
print(list(items1)) # [('张三', 15), ('李四', 25), ('王五', 35)] 列表中的元素是 元组 类型
字典元素的遍历
dict1 = {'张三': 15, '李四': 25, '王五': 35}
for item in dict1:
print(item) # 输出的是键 张三、李四、王五
print(dict1[item]) # 输出的是 值 15 25 35
字典的特点
- key不允许重复,value可以重复;一旦出现key重复,则后面的键值对会覆盖掉前面相同key的键值对
- 字典是无序的
- 字典的key必须是不可变对象
- 字典占用较大的内存,是一种以空间换取时间的数据结构
dict1 = {'张三': 15, '李四': 25, '王五': 35, '张三': 65}
print(dict1) # {'张三': 65, '李四': 25, '王五': 35}
字典生成式
- 语法格式:{表示字典key的表达式 : 表示字典value的表达式 for 自定义key的变量,自定义value的变量 in zip(可迭代对象keys,可迭代对象values)}
- 注意加上 {}
- 内置函数zip()
goods = ['Toy', 'Car', 'Tank']
prices = [15, 25, 35, 45, 55]
print(type(zip(goods, prices))) # <class 'zip'>
# 当键和值的列表的元素个数不一致时,以短的为基准
dict1 = {item.upper(): price for item, price in zip(goods, prices)} # upper() 是将字符串中的字母都转换成大写的方法
print(dict1) # {'TOY': 15, 'CAR': 25, 'TANK': 35}
python元组
-
元组:
- python内置的一个数据结构,是一个不可变序列
-
可变序列与不可变序列:
- 不可变序列:字符串、元组
- 不可变序列没有增删改操作
- 不可变序列:字符串、元组
str1 = 'lull'
print(str1) # lull
print(id(str1)) # 3103698323184
str1 = str1 + 'kkk'
print(id(str1)) # 3103698381488
print(str1) # lullkkk
可以看到,这样子似乎字符串确实进行了增加的操作,其实不然。这不是字符串的增加操作,只是在堆中开辟了一段空间 用来放 lullkkk,然后把这段空间的地址赋给了str1,原来的lull并没有消失
- 可变序列:列表、字典
- 可变序列可进行增删改操作,对象地址不改变
list1 = [10, 20, 30]
print(id(list1)) # 2103088052864
list1.append(40)
print(id(list1)) # 2103088052864
元组的创建方式
-
直接小括号
-
使用内置函数 tuple()
-
只包含一个元素的元组,需要使用 逗号 和 小括号
tuple1 = (10, 20, 30, 'tuple')
print(tuple1) # (10, 20, 30, 'tuple')
print(type(tuple1)) # <class 'tuple'>
tuple2 = tuple([10, 50, 60, 'tuple'])
print(tuple2) # (10, 50, 60, 'tuple')
print(type(tuple2)) # <class 'tuple'>
# 省略小括号
tuple3 = 10, 455, 12, 'tuple'
print(tuple3) # (10, 455, 12, 'tuple')
print(type(tuple3)) # <class 'tuple'>
# 单个元素的元组要加逗号
tuple4 = (15)
print(tuple4) # 15
print(type(tuple4)) # <class 'int'>
tuple5 = (15,)
print(tuple5) # (15,)
print(type(tuple5)) # <class 'tuple'>
tuple6 = 15,
print(tuple6) # (15,)
print(type(tuple6)) # <class 'tuple'>
- 空元组的创建方式
tuple1 = ()
tuple2 = tuple()
print(tuple1) # ()
print(tuple2) # ()
元组中的元素是不可变序列
- 元组中存储的是对其他对象的引用
- 如果元组中的元素本身是不可变序列,如int,str等,则不可以再引用其他对象,即不可以再改变它的值,因为改变它的值,会新开辟一段空间来存储这个值,然后指向这段空间
- 如果元组中的元素是可变序列,如列表,字典,则可变对象的引用不可变,但是可变对象的数据可以改变,因为可变对象指向的是一段空间的首地址,往可变对象中添加数据,或修改数据,可变对象指向的空间的首地址不会改变
tuple1 = (10, [20, 30], 40)
print(id(tuple1[1]))
tuple1[1].append(50) # 2918598900352
print(tuple1) # (10, [20, 30, 50], 40)
# tuple1[0] = 100 TypeError: 'tuple' object does not support item assignment 说明元组中的元素是不可变的
print(id(tuple1[0])) # 140733883162656
print(id(tuple1[1])) # 2918598900352
print(id(tuple1[2])) # 140733883163616
可以发现列表添加前后的id并没有发生改变
元组的遍历
元组是可迭代对象,可以利用for in来进行遍历
tuple1 = (10, [20, 30], 40)
for item in tuple1:
print(item) # 10 [20,30] 40
python集合
- 集合
-
- python内置的数据结构
- 与列表、字典一样是可变序列
- 集合是没有value的字典,所以它的元素存储位置,跟放入集合的先后顺序无关,同样要经过hash函数计算
- 集合中重复的元素只算一次
集合创建方式
- 使用 {}
set1 = {10, 20, 20, 20, 50, 30}
print(set1) # {10, 20, 50, 30}
print(type(set1)) # <class 'set'>
- 使用内置函数 set()
# 整数序列转换成集合
set1 = set(range(4))
print(set1, type(set1)) # {0, 1, 2, 3} <class 'set'>
# 将列表转换成集合
set2 = set([1, 2, 54, 65, 78, 1, 1, 2])
print(set2, type(set2)) # {65, 1, 2, 78, 54} <class 'set'> 可以发现,集合中的元素是无序的,即存放位置跟放入的先后顺序无关
# 将元组转换成集合
set3 = set((1, 2, 54, 65, 78, 1, 1, 2))
print(set3, type(set3)) # {65, 1, 2, 78, 54} <class 'set'>
# 将字符序列转换成集合
set4 = set('python')
print(set4, type(set4)) # {'p', 'o', 'h', 't', 'n', 'y'} <class 'set'>
# 将集合转换成集合,没啥子用
set5 = set({1, 2, 54, 65, 78, 1, 1, 2})
print(set5, type(set5)) # {65, 1, 2, 54, 78} <class 'set'>
# 创建空集合
set6 = set()
print(set6, type(set6)) # set() <class 'set'>
集合的相关操作
集合元素的判断操作
- in 或 not in
set1 = {10, 20, 30, 40}
print(10 in set1) # True
print(50 not in set1) # True
集合元素的新增操作
- add() 一次添加一个元素
set1 = {10, 20, 30, 40}
set1.add(50)
print(set1) # {40, 10, 50, 20, 30}
- update() 添加多个元素
set1 = {10, 20, 30, 40}
# update 里面放集合
set2 = {50, 60, 20}
set1.update(set2)
print(set1) # {50, 20, 40, 10, 60, 30}
# update 里面放列表
set1.update([70, 80, 20])
print(set1) # {80, 50, 20, 70, 40, 10, 60, 30}
# update 里面放元组
set1.update((90, 100, 'set'))
print(set1) # {70, 10, 80, 20, 90, 30, 100, 40, 50, 'set', 60}
集合元素的删除操作
- remove() 删除集合中的指定元素,如果要删除的元素在集合中不存在,则会抛出keyError异常
set1 = {10, 20, 30, 40}
set1.remove(40)
print(set1) # {10, 20, 30}
# set1.remove(100) KeyError: 100
- discard() 一次删除集合中的一个指定元素,如果要删除的元素在集合中不存在,不会抛出keyError异常
set1 = {10, 20, 30, 40}
set1.discard(40)
print(set1) # {10, 20, 30}
set1.discard(100)
print(set1) # {10, 20, 30}
- pop() 一次删除第一个元素,没有参数,特别注意,这里说的第一个元素并不是放入的第一个元素,而是集合中存放好的第一个元素
set1 = {10, 20, 30, 40}
# print(set1) {40, 10, 20, 30}
set1.pop() # 要特别注意,这里删掉的并不是10,因为集合中的元素是无序的,存放位置跟放入顺序无关,先输出set1,可以看到40在第一个
print(set1) # {10, 20, 30}
set1.pop()
print(set1) # {20, 30}
- clear() 清空集合
set1 = {10, 20, 30, 40}
set1.clear()
print(set1) # set()
集合的相关关系
两个集合是否相等
- 利用 == 或 !=
set1 = {10, 20, 30, 40}
set2 = {20, 10, 40, 30}
print(set1 == set2) # True
print(set1 != set2) # False
一个集合是否是另一个集合的子集
- issubset()
set1 = {10, 20, 30, 40}
set2 = {20, 10}
print(set2.issubset(set1)) # True
一个集合是否是另一个集合的超集(类似于父集)
- issuperset()
set1 = {10, 20, 30, 40}
set2 = {20, 10}
print(set1.issuperset(set2)) # True
两个集合是否有交集
- isdisjoint() 没有交集为True,有交集为False
set1 = {10, 20, 30, 40}
set2 = {20, 50, 60}
set3 = {98, 87}
print(set1.isdisjoint(set2)) # False
print(set1.isdisjoint(set3)) # True
集合的数学操作
交集
- intersection() 或者是 &
- 两个集合进行交集前后自身并不会发生变化
set1 = {10, 20, 30, 40}
set2 = {20, 50, 60}
set3 = {98, 87}
print(set1.intersection(set2)) # {20}
print(set1 & set2) # {20}
并集
- union() 或者是 |
- 两个集合进行并集前后自身并不会发生变化
set1 = {10, 20, 30, 40}
set2 = {20, 50, 60}
set3 = {98, 87}
print(set1.union(set2)) # {50, 20, 40, 10, 60, 30}
print(set1 | set2) # {50, 20, 40, 10, 60, 30}
差集
- difference() 或 -
- 两个集合进行差集前后自身并不会发生变化
set1 = {10, 20, 30, 40}
set2 = {20, 50, 60}
set3 = {98, 87}
print(set1.difference(set2)) # {40, 10, 30}
print(set2 - set1) # {50, 60}
对称差集
- symmetric_difference() 或 ^
- 两个集合同样不发生改变
set1 = {10, 20, 30, 40}
set2 = {20, 50, 60}
set3 = {98, 87}
print(set1.symmetric_difference(set2)) # {40, 10, 50, 60, 30}
print(set2 ^ set1) # {40, 10, 50, 60, 30}
集合生成式
- 只有可变序列才有生成式,所以列表、字典、集合都有生成式;而元组没有
- 格式: {表示集合元素的表达式 for 自定义变量 in 可迭代对象}
- 注意加上 {}
set1 = {i * i for i in range(10)}
print(set1) # {0, 1, 64, 4, 36, 9, 16, 49, 81, 25}
print(type(set1)) # <class 'set'>
python字符串
字符串的驻留机制
Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符津的地址赋给新创建的变量
str1 = 'python'
str2 = "python"
str3 = '''python'''
print(str1, id(str1)) # python 1624204707312
print(str2, id(str2)) # python 1624204707312
print(str3, id(str3)) # python 1624204707312
可以发现即使定义了三个变量,但是三个变量执行的内存空间是同一个。原因是,当str1=‘python’时,首先创建一段空间用来存储python,然后str1指向这段空间,然后后续发现在内存中存在’python’,所以str2和str3直接指向这段空间,不用在新建空间来存放’python’
驻留机制的几种情况(在交互模式下执行,即终端)
- 字符串长度为0或1
- 符合标识符的字符串
- 字符串只在编译时驻留,而非运行时
a是编译时确定,b利用 + 号进行字符串拼接,也是编译时确定,而c是运行时,利用join方法进行字符串拼接,即使三者的内容一直,但是c的标识跟前二者不一致
- [-5,256] 之间的整数数字
- 使用sys中的intern()强制驻留
以上在Pycharm中可能会得到不一样的结果,因为pycharm对字符串进行了优化,都强制驻留
驻留机制的优缺点
- 当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是会比较影响性能的
- 在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()方法是先计算出所有字符中的长度,然后再拷贝,只new一次对象,效率要比"+"效率高
字符串的常见操作
查询操作
- index() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError
- rindex() 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError
- find() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1
- rfind() 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回-1
str1 = 'hello,hello'
print(str1.index('lo')) # 3
print(str1.rindex('lo')) # 9
# print(str1.index('wo')) ValueError: substring not found
print(str1.find('lo')) # 3
print(str1.rfind('lo')) # 9
print(str1.rfind('wo')) # -1
大小写转换操作
- upper() 把字符串中所有字符都转成大写字母
- lower() 把字符串中所有字符都转成小写字母
- swapcase() 把字符串中所有大写字母转成小写字母,把所有小写字母都转成大写字母
- capitalize() 把第一个字符转换为大写,把其余字符转换为小写
- title() 把每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写
str1 = 'hello,hello'
str2 = 'WORld,woRld'
print(str1.upper()) # HELLO,HELLO
print(str1) # hello,hello str1并没有发生改变
print(str2.lower()) # world,world
print(str2.swapcase()) # worLD,WOrLD
print(str2.capitalize()) # World,world
print(str2.title()) # World,World
字符串内容对齐操作
- center() 居中对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格.如果设置宽度小于实际宽度则则返回原字符串
- ljust() 左对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格如果设置宽度小于实际宽度则则返回原字符串
- rjust() 右对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格如果设置宽度小于实际宽度则则返回原字符串
- zfill() 右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串的长度,返回字符串本身
str1 = 'hello'
print(str1.center(10, '*')) # **hello***
print(str1.ljust(10, '*')) # hello*****
print(str1.rjust(10, '*')) # *****hello
print(str1.zfill(10)) # 00000hello
print('-564'.zfill(8)) # -0000564
字符串的分割操作
- split()
- 从字符串的左边开始分割,默认的分割字符是空格字符串,返回的值都是一个列表
- 以通过参数sep指定分割字符串是的分割符
- 通过参数maxsplit指定分割字符串时的最大分割次数,在经过最大次分割之后,剩余的子串会单独做为一部分
str1 = 'hello world wwj'
print(str1.split()) # ['hello', 'world', 'wwj']
print(str1.split(sep='w')) # ['hello ', 'orld ', '', 'j']
print(str1.split(sep='w', maxsplit=1)) # ['hello ', 'orld wwj']
- rsplit()
- 从字符串的右边开始分割,默认的分割字符是空格字符串,返回的值都是一个列表
- 以通过参数sep指定分割字符串是的分割符
- 通过参数maxsplit指定分割字符串时的最大分割次数,在经过最大次分割之后,剩余的子串会单独做为一部分
str1 = 'hello world wwj'
print(str1.rsplit()) # ['hello', 'world', 'wwj']
print(str1.rsplit(sep='w')) # ['hello ', 'orld ', '', 'j']
print(str1.rsplit(sep='w', maxsplit=1)) # ['hello world w', 'j']
判断字符串的操作
- isidentifier() 判断指定的齐符串是不是合法的标识符
- issplace() 判断指定的字符串是否全部由空白字符组成(回车、换行,水平制表符)
- isalpha() 判断指定的字符串是否全部由字母组成
- isdecimal() 判断指定字符串是否全部由十进制的数字组成
- isnumeric() 判断指定的字符串是否全部由数字组成
- isalnum() 判断指定字符串是否全部由字母和数字组成
print('abc%'.isidentifier()) # False
print('随_'.isidentifier()) # True
print('4_kj'.isidentifier()) # False
print('ajkh'.isidentifier()) # True
print(' a '.isspace()) # False
print(' '.isspace()) # True
print('\n'.isspace()) # True
print(' a '.isalpha()) # False
print('a'.isalpha()) # True
print('随'.isalpha()) # True
print('随_'.isalpha()) # False
print('123'.isdecimal()) # True
print('123四'.isdecimal()) # False
print('ⅠⅤ'.isdecimal()) # False
print('123'.isnumeric()) # True
print('123四'.isnumeric()) # True
print('ⅠⅤ'.isnumeric()) # True
print('abc456'.isalnum()) # True
print('随456'.isalnum()) # True
print('456!'.isalnum()) # False
字符串的替换操作
- replace() 第1个参数指定被替换的子串,第2个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换前后的原字符串不发生变化,调用该方法时可以通过第3个参数指定最大替换次数
str1 = 'hello,world,hello,wwj'
str2 = str1.replace('hello', 'nice') # 不指定第三个参数,默认全部替换
print(str2) # nice,world,nice,wwj
print(str1) # hello,world,hello,wwj
str3 = str1.replace('hello', 'nice', 1)
print(str3) # nice,world,hello,wwj
字符串的合并操作
- join() 将列表或元组中的字符串合并成一个字符串
list1 = ['hello', 'world', 'wwj']
tuple1 = ('hello', 'world', 'wwj')
str1 = '$'.join(list1) # 以 '$' 为分隔符进行拼接
print(str1) # hello$world$wwj
str2 = '¥'.join(tuple1) # 以 '¥' 为分隔符进行拼接
print(str2) # hello¥world¥wwj
print('*'.join('Python')) # P*y*t*h*o*n
字符串的比较操作
- 运算符:<,>,==,<=,>=,!=
- 比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较
- 比较原理:两上字符进行比较时,比较的是其ordinal value(原始值),调用内置函数ord可以得到指定字符的ordinal value。与内置函数ord对应的是内置函数chr,调用内置函数chr时指定ordinal value可以得到其对应的字符。两个字符进行比较,比较的是ASCLL十进制值
print('apple' > 'app') # True
print('apple' > 'banana') # False
print(ord('a'), ord('b')) # 97 98
print(chr(99), chr(102)) # c f
字符串的切片操作
- 与列表的切片操作类似
str1 = 'hello,Python'
str2 = str1[:5]
str3 = str1[6:]
str4 = str2 + '!\t' + str3
print('str1', str1, id(str1)) # str1 hello,Python 2163801786032
print('str2', str2, id(str2)) # str2 hello 2163801844720
print('str3', str3, id(str3)) # str3 Python 2163801844784
print('str4', str4, id(str4)) # str4 hello! Python 2163801844848
print(str1[::-1]) # nohtyP,olleh
print(list(str1[::-1])) # ['n', 'o', 'h', 't', 'y', 'P', ',', 'o', 'l', 'l', 'e', 'h'] 从右往左开始切片,因为步长为负数
print(str1[-6::1]) # Python 索引值为负数,最后一个元素的索引值为-1,从左往右开始切片
可以发现四个字符串的存储位置各不相同
格式化字符串
格式化字符串的两种方式:
-
% 做占位符
-
%s 表示 字符串;%d 表示 整数;%f 表示 浮点数
-
{} 做占位符
-
f’字符串内容’
name = 'wwj'
age = 20
# % 做占位符
print('%s今年%d岁了' % (name, age)) # wwj今年20岁了
# {} 做占位符
print('我的名字是{0},今年{1},我的姓名是{0}'.format(name, age)) # 我的名字是wwj,今年20,我的姓名是wwj
print(f'我的名字是{name},今年{age},我的姓名是{name}') # 我的名字是wwj,今年20,我的姓名是wwj
# d 前面的数字表示数的宽度
print('%10d' % 23)# 23
# f 前面的 .3 表示浮点数的小数位数
print('%.3f' % 3.141526)#3.142
# f 前面的 10.3 表示浮点数的宽度以及小数位数
print('%10.3f' % 3.141526)# 3.142
# 只有一个数时,{}里面的 0 可写可不写,但是有两个以上的数时,{}里面必须要有数字,0必须写上;不管是不是一个数,最好还是把0写上
print('{}'.format(3.1415926))
print('{0}'.format(3.1415926))
print('{0:.3}'.format(3.1415926)) # 3.14 .3 没加f 表示三个数字
print('{0:.3f}'.format(3.1415926)) # 3.142 .3f 表示三位小数
print('{0:10.3f}'.format(3.1415926)) # 3.142 右对齐 10.3f 表示数的宽度是10,3位小数
字符串的编码转换
需要字符串编码转换的原因:
编码与解码的方式:
- 编码:将字符串转换成二进制数据(bytes) encode()
str1 = '奥利给'
print(str1.encode(encoding='GBK')) # b'\xb0\xc2\xc0\xfb\xb8\xf8' 可以发现在GBK中,一个中文字符占 两个字节
print(str1.encode(encoding='utf-8')) # b'\xe5\xa5\xa5\xe5\x88\xa9\xe7\xbb\x99' 可以发现在utf-8中,一个中文字符占 三个字节
- 解码:将二进制数据(bytes)转换成字符串类型 decode()
GBK_byte = b'\xb0\xc2\xc0\xfb\xb8\xf8'
print(GBK_byte.decode(encoding='GBK')) # 奥利给
utf_8_byte = b'\xe5\xa5\xa5\xe5\x88\xa9\xe7\xbb\x99'
print(utf_8_byte.decode(encoding='utf-8')) # 奥利给