python线性数据结构 --tuple和str

本文使用到的函数
项目 函数
元组 index() ; count() ; len()
字符串查询 find()/rfind() ; index() ; count() ; len()
字符串分割 split()/rsplit(); splitlines() ;partition()/rpartition()
字符串查询 replace()
字符串移除 strip() ; rstrip()/lstrip()
字符串首尾判断 endswith() ; startswith()
其他函数 见本文具体科目

元组tuple

1.一个有序元素组成的集合
2.使用小括号来封装元素
3.元素不可改变,字面常量元素不可修改
4.引用类型元素中的子元素可以修改,但是引用类型本身地址没有发生变化,因此引用类型元素的子元素可以适当修改

初始化

tuple() -> empty tuple
tuple(iterable) -> tuple initialized from iterable’s items

t1=()
t2=(1,)  #二元组,这个逗号必须添加,不然t2就变成了一个整型数据
t3=(1,2,3) #三元组
t4=(1,)*5 #生成五元组
t5=1,'a' #初始化时使用逗号
t6=(1,2,3,1,2,3,) ##元素可以重复
t7=tuple() #生成空元祖
t8=tuple(range(10)) #生成元组
t9=tuple([1,2,3]) #使用列表生成元组

索引

元组索引的使用和列表的使用规则是一样的:不可以超界
具体使用方式可以查看列表的索引:列表索引

>>> s1=('a','1',2,33,[2,3],(1,'a'))
>>> s1[1],s1[5][1]  
('1', 'a')

元组的查询

方法和列表一样,时间复杂度也是一样的。index,count,len等函数
index函数
返回某个value的索引值,会遍历元组,时间复杂度为O(n)

index函数的语法模式:
s1.index(value, start_index, stop_index)
>>> s1=('a','1',2,33,[2,3],(1,'a'))
>>> s1.index((1,'a'),2)        ##默认的index范围为[0,len(tuple))前闭后开区间
5
>>> s1.index((1,'a'),2,5)      #这样会报错,报元组中没有此元素,因为2,5的区间是不包含5的
>>> s1.index((1,'a'),2,100)    #这个是可以执行的,但是直接通过索引来访问的话,如果索引超界就会报错,如下
>>> s1[100]  
IndexError: tuple index out of range

count函数
返回某个value在元组中出现的次数:会遍历元组,时间复杂度为O(n)

count函数语法模式:
s1.count(value)
>>> s1=('a','1',2,33,[2,3],(1,'a'),'a')
>>> s1.count('a')      ##此value不会返回元素中引用类型中的元素
2

len函数
直接返回元组的的长度,因为元组的长度就记录在元组的元数据中,因此len函数的时间复杂度为O(1)

len函数的语法模式:
len(object),len函数直接调用对象即可执行
>>> s1=('a','1',2,33,[2,3],(1,'a'),'a')
>>> len(s1)
7

tuple元素操作

元组元素的个数已经在初始化时就决定好了,因此不能增加元组的元素个数也不能删除元组中的元素
注意:元组在定义时逗号很重要

>>> t1 = ([1]) * 3   ##由于t1在定义时元素后面没有添加逗号,因此t1其实是一个列表
>>> t1[1] = 100 # ?
>>> print(type(t1))
<class 'list'>

修改引用类型元素中的子元素不会改变引用类型地址,但是如果使用乘法来生成元组,其中的引用类型就会批量改变

>>> t1=([1],)*3
>>> t1[1][0]=100   ##修改第二个元素中的第一个子元素,由于这是引用类型,因此可以修改成功,但是由于元组是使用乘法生成的,
>>> print(t1)	   ##因此每个引用类型元素的地址都是一样的,一旦一个改变,其他的都会跟着改变
([100], [100], [100])

直接修改引用类型元素,这会导致引用类型元素的改变,因此,在元组中这是不可能成功的

>>> t1=([1],)*3
>>> t1[1]=100  ##这就相当于将引用类型元素改编成整型元素100,这是修改元素,因此在元组中会报错
TypeError: 'tuple' object does not support item assignment

字符串str

1.由一个个字符组成的有序的序列
2.使用单引号,双引号或三引号包围
3.字符串是字面常量,不可改变
4.想得到需要的字符串可以使用新增字符串的方式
5.python3之后字符串的类型都是Unicode类型

>>> print(type('aaa'))
<class 'str'>    ##字符串类型

初始化
字符串的初始化直接使用赋值语句即可完成,字符串内容使用单引号,双引号,三引号来包围。还可以使用R,r,f前缀来完成特殊功能

s1='string'        #使用单引号包围
s2="string2"       #使用双引号包围
s3='''this is a "string",'啦啦啦''''  ##使用三引号包围
s4='hello \n world'  ##换行符会换行
s5=r'hello \n world' ##r前缀会导致后续字符串中的转义字符失效,\n不会换行,只会打印'\n'这两个字符
s6='c:\windows\nt'   ##也会被换行
s7=R"c:\windows\nt"  ##不会换行,R前缀有着r前缀类似的功能
s8='c:\windows\\nt'  ##不会换行,因为第二个\已经被转义,打印出来的结果为c:\windows\nt
name='tom'
age=22
s9=f'{name}:{age}'  ##可以使用f前缀来格式化输出
s10="""select * from student where name='tom'""" 

索引

字符串是有序序列,可以使用索引来访问,索引的范围也是从0开始,但是不能通过索引来修改

>>> s10="""select * from student where name='tom'""" 
>>> s10[3] ##字符e
>>> s10[4]=a  ##这样会报错,因为字符串是字面常量,不可修改
TypeError: 'str' object does not support item assignment

连接

+加号:

将两个字符串连接起来组成一个新的字符

>>> str1='name'
>>> str2='tom'
>>> print(str1+':'+str2)  ##可以添加多个字符和字符串,使用加号‘+’连接

join函数:
sep.join(iterable)

使用指定字符串作为分隔符,将可迭代对象中的各个字符使用分隔符连接起来
可迭代对象必须是个字符串
将会生成一个新的字符串

>>> L1=['a','b','c']
>>> str=''.join(L1)  ##将分隔符设置为空,这样就能无缝连接 列表中的各个元素
>>> print(str)
abc

>>> import random
>>> random.sample('abcdefghijklmnopqrstuvwxyz',2)
['q', 'e']  ##生成的是一个列表
>>> str2=''.join(random.sample('abcdefghijklmnopqrstuvwxyz',2)) ##使用join函数来组合random生成的元素
>>> print(str2)
wq

print('-'.join(range(5)))

这种格式是不行的,因为range生成的是整形数据,而join需要的是字符串,因此会报错

>>> print('-'.join(range(5))) 
TypeError: sequence item 0: expected str instance, int found

字符串查询

find函数、index函数和count函数
find函数

  • find(sub,start[,end]) --> int
    在指定的区间内[start,end),查找子串sub,这个区间是左闭右开区间
>>> s = 'heiedu.edu'
>>> print(s.find('edu'))
>>> print(s.find('edu', 3))
>>> print(s.find('edu', 4))
>>> print(s.find('edu', 6, 9))
>>> print(s.find('edu', 7, 20))
>>> print(s.find('edu', 200))
3
3
7
-1
7
-1
  • rfind(sub,start[,end]) --> int
    在指定的区间内[start,end),查找子串sub,这个区间也是左闭右开区间
    不管是find还是rfind函数,索引的范围都是正索引,并且顺序都是从左至右依次增大,只是查找时方向相反而已
>>> s = 'magedu.edu'
>>> print(s.rfind('edu'))
>>> print(s.rfind('edu', 3))
>>> print(s.rfind('edu', 4))  ##索引的范围从4开始向右增加,查找时从右至左开始查找,找到第一个即返回正索引
>>> print(s.rfind('edu', 6, 9)) ##依然不包括索引9,所以找不到字符串
>>> print(s.rfind('edu', 7, 20)) 
>>> print(s.rfind('edu', 200)) #从索引200开始查找,肯定找不到,返回-1
>>> print(s.rfind('edu', -100))  ##索引范围可以超限,只要在所包含的范围内找到字符串即可返回其正索引
7
7
7
-1
7
-1
7

index函数

index(sub,start(,end)) --> int
rindex(sub,start(,end)) --> int

index函数的用法和find函数类似,只不过在找不到符合条件的值时会返回ValueError错误

count函数
在指定的区间内统计字符串出现的次数

count(sub,start(,end)) -->int

时间复杂度

1.find函数,index函数和count函数的时间复杂度都为O(n)
2.find会遍历字符串,直到找到符合条件的字符串为止
3.index函数跟find函数一样
4.count必定会遍历字符串

len函数

1.直接返回字符串的长度
2.时间复杂度为O(1)
3.len值保存在字符串的元数据中

字符串分割

字符串分割常用的函数主要包括这几种:split函数,rsplit函数,splitlines函数,partition函数,rpartition函数

split函数和splitlines函数

split(sep=None[,maxsplit=n]) --> list of str 按照sep符来切割字符串,maxsplit表示最大的切割次数,默认为全部切割,设置-1也表示全部切割
rsplit(sep=None[,maxsplit=n]) --> list of str从右边开始切割,不过返回的列表仍然是从左至右显示
splitlines(keepends) --> list of str按照行来切割字符串,keepends表示是否保留行分隔符      
split函数和splitlines函数的区别:

split函数在分割时会返回分割符两端的字符,如果分割后某端没有字符,则会返回一个空字符,用单引号包围
split函数在分割空字符串时,会返回一个包含空字符的非空列表
split函数默认分隔符为空格
splitlines函数分割则不同,在分割空字符串时,会返回一个空列表
splitlines函数在处理字符串末尾的换行符时,不会导致一个新行产生,但split函数则会产生新的分割段

>>> "".split('\n'), "Two lines\n".split('\n')
([''], ['Two lines', ''])       #返回包含空字符的非空列表,末尾分隔符会导致新行的产生
>>> "".splitlines(), "One line\n".splitlines()
([], ['One line'])              #返回空列表,末尾分隔符不会导致新行产生
>>> x='a-b-c-d-e-f-g'
>>> x.split('-',maxsplit=-1)
['a', 'b', 'c', 'd', 'e', 'f', 'g']

>>> x='a b c d'
>>> x.split()
['a', 'b', 'c', 'd']

>>> x='a-b-c-d-e-f-g'
>>> x.rsplit('-')      #不设置maxsplit时默认为全部分割
['a', 'b', 'c', 'd', 'e', 'f', 'g'] #从右边开始切割时,显示的顺序仍然是从左至右

>>> x='a\n_aaa\neeee\n\rma'  ##行分隔符有\n,\r,\r\n
>>> x.splitlines() #splitlines默认按换行符切割
['a', '_aaa', 'eeee', '', 'ma']  ##连续两个分隔符时,中间会有一个空字符

>>> x='\na\n_aaa\neeee\n\rma\naa\n'
>>> x.splitlines(keepends=1)  ##设置keepends为1可以显示行分隔符
['\n', 'a\n', '_aaa\n', 'eeee\n', '\r', 'ma\n', 'aa\n']

>>> x='\na\n_aaa\neeee\n\rma\naa\n'
>>> x.splitlines()
['', 'a', '_aaa', 'eeee', '', 'ma', 'aa'] ##与上个例子对比可以发现,行分隔符在字符串头部时会出现一个空字符
										  ##或者连续两个行分隔符也会多一个空字符

partition函数与rpartition函数

partition(sep) --> (head,sep,tail) 从左至右,遇到分隔符就将字符串分割成两部分,返回一个三元组(前一部分,分隔符,后一部分)
rpartition(sep) -->(head,sep,tail) 与partition相反。

注意事项:
- 分隔符sep必须指定
- partition如果没有匹配到分隔符,那么就返回(整个字符串,空字符,空字符)
- rpartition如果没有匹配到分隔符,那么就返回(空字符,空字符,整个字符串)
- 分隔符都放在三元组的中间

>>> x='a b c d'
>>> x.partition(' ')
('a', ' ', 'b c d')

>>> x='a-b-c-d'
>>> x.partition(',')
('a-b-c-d', '', '')

>>> x='a-b-c-d'
>>> x.rpartition(',')
('', '', 'a-b-c-d')

字符串替换

replace()

replace(old,new[,count]) --> str
字符中找到匹配项就替换,然后返回一个新的字符串
count表示替换的次数,默认为全部替换
>>> a='www.baidu.com'
>>> a.replace('www','web')
web.baidu.com

>>> a='www.baidu.com'
>>> a.replace('w','a',2)  ##只替换两次
aaw.baidu.com

字符串移除

strip函数,lstrip函数,rstrip函数

strip([chars]) --> str #移除字符串两端的包含在chars字符集中的字符
lstrip([chars]) -->str #移除字符串左侧的相应字符
rstrip([chars]) -->str #移除字符串右侧的相应字符
x=' ' + 'www.aaa.www' #先在字符串左侧加上一个空字符
print(x.strip())   #默认去除字符串两端的空字符
print(x.strip('w')) #去除字符串两端的w字符
print(x.rstrip('w')) #去除字符串右侧的w字符
print(x.lstrip('w')) #去除字符串左侧的w字符
www.aaa.www  #去除了左侧的空字符
 www.aaa.    #左侧有空字符,所以只去除了右侧的w字符
 www.aaa.    #只去除右侧的w字符
 www.aaa.www #左侧有空字符,因此字符串不做修改

字符串首尾判断

startswith函数和endswith函数

startswith(suffix[,start[,ends]]) --> bool#在指定区间内字符串是否以suffix开始
endswith(suffix[,start[,ends]]) --> bool#在指定区间内字符串是否以suffix结束
x='www.baidu.com'
print(x.startswith('ww')) #符合条件
print(x.startswith('w',2)) #符合条件
print(x.startswith('com',9))#索引9开始的字符串是".com",不符合条件
print(x.endswith('com')) #符合条件

其他函数

upper()大写,字符串转换
lower()小写
swapcase() 交换大小写
isalnum() -> bool 是否是字母和数字组成
isalpha() 是否是字母
isdecimal() 是否只包含十进制数字
isdigit() 是否全部数字(0~9)
isidentifier() 是不是字母和下划线开头,其他都是字母、数字、下划线,判断是不是标识符
islower() 是否都是小写
isupper() 是否全部大写
isspace() 是否只包含空白字符
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章