6.1_5 Python3.x入门 P5 【基础】不可变序列(元组tuple、字符串str)

相关链接

  • 目录
  • Mac M1 Python环境搭建
  • Python3.x入门 P1 【基础】注释、标识符、变量、数据类型
  • Python3.x入门 P2 【基础】运算符
  • Python3.x入门 P3 【基础】流程语句【循环结构】
  • Python3.x入门 P4 【基础】可变序列(列表list、字典dict、集合set)
  • Python3.x入门 P5 【基础】不可变序列(元组tuple、字符串str)

一、序列

可变序列:可以对执行序列进行增、删、改操作,对象地址不发生改变。

    ① 列表list -> [v1,v2,…]、② 集合set -> {k1,k2,…}、③ 字典dict -> {k1:v1,…}

不可变序列:没有增、删、改的操作。由于其不可变特性,在多线程场景下,不需要加锁。

    ① 元组tuple -> (v1,v2,…) 、② 字符串str -> ‘’


1.1 可变序列&不可变序列

"""
 @author GroupiesM
 @date 2022/6/22 16:11
 @introduction
 可变序列:列表list、字典dict、集合set
          可以对执行序列进行增、删、改操作,对象地址不发生改变
 不可变序列:元组tuple、字符串str
           没有增、删、改的操作
"""
'''可变序列 列表list、字典dict、集合set'''
lst = [10, 20, 45]
lst.append(300)
print(lst)  # [10, 20, 45, 300]

'''不可变序列 元组tuple、字符串str'''
t = ('python', 5)
print(t)  # ('python', 5)

1.2 不可变序列&多线程

"""
 @author GroupiesM
 @date 2022/4/29 09:25
 @introduction
    不可变序列(元组、字符串)在多个线程场景下,同时操作同一对象时不需要加锁

 注意事项:
    元组中存储的是对象的引用
    a) 如果元组中对象本身不可变对象,即指向的内存地址不可变
    b) 如果元组中的对象是非基本类型,可以修改其中的数据
"""
t = (10, [20, 30], 9)
print(t)  # (10, [20, 30], 9)

'''元组中的元素是引用类型时,可以修改引用类型的数据'''
t[1].remove(30)  # (10, [20], 9)
print(t)  # (10, [20], 9)

'''不可以修改元素的内存地址'''
t[1] = [50]
print(t)  # TypeError: 'tuple' object does not support item assignment

1.3 总结

数据结构 可变序列 值可重复 是否有序 定义符号
列表(list) [v1,v2,…]
集合(set) × × {k1,k2,…}
字典(dict) key(×) value(√) × {k1:v1,k2:v2,…}
元组(tuple) × (v1,v2,…)

P.S:
  1.不可变序列在内存中是不会改变的

  2.如果对不可变序列做出改变,会将该序列存储在新的地址空间中,而原来的序列因为垃圾回收机制,会被回收。

  3.可变序列发生改变时,是不会改变地址的,而是改变内存中的值,或者是扩展内存空间。

  4.字典是一个可变序列,但是字典的键是不可变的,而值是可变的。因为字典结构的原理是伪随机探测的散列表,它的查找方式是将键通过哈希函数,找到值的内存地址。所以哈希后的值一般是唯一的或是冲突比较小的。如果改变键的值,name哈希后的值就会发生变化,导致找不到原来的值,所以键的值是不可变的。键哈希后指向的是内存中的地址,内存中的数据发生变化不影响字典的查找。


二、元组tuple -> (v1,v2,…)

2.1 简介

"""
 @author GroupiesM
 @date 2022/4/28 17:13
 @introduction 

 列表:list = ['hello', 'world', 100]
 字典:dict = {'name': '张三', 'age': 100}
 元组:tuple = ('python','hello',90)
 集合: set  = {'python', 'hello', 90}
 字符串: str = 'python'
"""
t = ('python', 'hello', 90)
print(type(t))  # 
print(t)  # ('python', 'hello', 90)

2.2 创建

"""
 @author GroupiesM
 @date 2022/4/28 17:55
 @introduction

元组创建方式:
    方式一:使用小括号(),元素之间英文逗号分隔;只有一个元素时也要加逗号,否则数据类型为基本数据类型
        tup = ('python',)
        tup = (1,3,5)
    方式二:内置函数 tuple() 类型转换
        tuple(('hello','php'))                   # list -> tuple
        tuple({'name': '张三', 'age': 100})       # 字典 -> tuple
        tuple(['hello','php'])                   # 元组 -> tuple
        tuple({'python', 'hello', 90})           # 集合 -> tuple
        tuple('hello')                           # 字符串->tuple
"""
'''方式一'''
lst = ['hello', 'python']
print(lst)  # ['hello', 'python']

'''方式二'''
'''1.list->tuple'''
lst1 = tuple(('hello', 'php'))  # list -> tuple
print('lst1', lst1) # ('hello', 'php')

'''2.字典->tuple时,自动取字典的key'''
lst2 = tuple({'name': '张三', 'age': 100})  # 字典 -> tuple
print('lst2', lst2) # ('name', 'age')

'''3.元组->tuple'''
lst3 = tuple(['hello', 'php'])  # 元组 -> tuple
print('lst3', lst3) # ('hello', 'php')

'''4.集合->tuple'''
lst4 = tuple({'python', 'hello', 90})  # 集合 -> tuple
print('lst4', lst4) # ('python', 'hello', 90)

'''5.字符串->tuple'''
lst5 = tuple('hello')  # 字符串->tuple
print('lst5', lst5) # ('h', 'e', 'l', 'l', 'o')

2.3 遍历

"""
 @author GroupiesM
 @date 2022/4/29 15:04
 @introduction
    使用for-in遍历:
        元组是可迭代对象
        t = ('Python','hello',90)
        for i in t:
            print(i)
"""
t = ('Python', 'hello', 90)
for i in t:
    print(i, end="\t")  # Python	hello	90

print()
for i in range(0, len(t)):
    print(t[i], end="\t")  # Python	hello	90

三、字符串str -> ‘’

"""
 @author GroupiesM
 @date 2022/6/27 16:57
 @introduction 
"""
    1.查询的方法
        index(): 查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError
        rindex():查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError
        find():查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1
        rfind():查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回-1
    2.大小写转换
        upper(): 把字符串中所有的字符都转成大写字母
        lower(): 把字符串中所有的字符都转成小写字母
        swapcase(): 把字符串中所有大写字母转成小写字母,把所有小写字母转成大写字母
        capitalsize(): 整个字符串首字母大写,其余字母小写
        title(): 每个单词首字母大写,其余字母小写
    3.内容对齐
        center(): 居中对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
        ljust(): 左对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
        rjust(): 右对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
        zfill(): 右对齐,左边用0填充,第1个参数指定宽度,如果设置宽度小于实际宽度则返回原字符串
    4.字符串的分割
        split(self,sep,maxsplit):从字符串左边开始分割,返回一个列表
            self:字符串本身
            sep:指定分隔符,默认为空格
            maxsplit:指定最大分割次数,分割指定次数后,剩余字符串作为一个整体不再分割
        rsplit():从字符串右边开始分割,返回一个列表(参数相同)
    5.字符串判断
        isidentifier(): 合法的变量名(可用作接收变量的变量名)
        isspace(): 全部由空字符串组成(回车、换行、水平制表符)
        isalpha(): 全部由字母组成
        isdecimal(): 全部由十进制的数字组成
        isnumeric(): 全部由数字组成(中文简体、繁体,符号,罗马数字)
        isalnum(): 全部由字母和数字组成
    6.字符串替换
        replace(old,new):
        replace(old,new,count):
            self: 默认字符串本身
            1.old: 替换前的字符串
            2.new: 替换后的字符串
            3.count: 最大替换次数,(可省略参数)
    7.字符串合并
        join(): 将列表或元组中的字符串合并成一个字符串,列表或元组的元素必须都是字符串
    8.字符串比较
        运算符:>,>=,<,<=,==,!=
            比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,
            依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的
            比较结果,两个字符串中所有的后续字符将不再被比较
        比较原理:
            两个字符进行比较,比较的是其 ASCII码值
            通过内置函数ord(字符),可以获取字符对应的 ASCII码值(数字)
            通过内置函数chr(数字),可以获取数字对应的 字符
    9.字符格式化
            %-formatting、format、f-String
    10.字符串编解码
        encode(String encoding):编码,将字符串转换为二进制数据(bytes)
        decode(String encoding):解码,将bytes类型的数据转换为字符串类型

3.1 简介

"""
 @author GroupiesM
 @date 2022/5/9 14:03
 @introduction 

 列表:list = ['hello', 'world', 100]
 字典:dict = {'name': '张三', 'age': 100}
 元组:tuple = ('python','hello',90)
 集合: set  = {'python', 'hello', 90}
 字符串: str = 'python'
"""
'''
字符串定义:有三种方式,单引号、双引号、三引号
'''
str1 = 'python'
str2 = "python"
str3 = ''''python'''
print(type(str1))  # 
print(str1)  # ('python', 'hello', 90)

3.2 驻留机制

"""
 @author GroupiesM
 @date 2022/5/9 14:14
 @introduction
一、驻留机制
    1)python中字符串是基本类型,是不可变字符序列
    2)什么是字符串驻留机制 【相同字符串的内存地址也相等】
        仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,
        Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,
        不会开辟新空间,而是把该字符串的地址赋值给新建的变量

二、注意事项
    1、字符串的驻留条件
        仅包含字母、数字、下划线的字符串,python会启用驻留机制,
        因为Python解释器仅对看起来像python标识符的字符串使用intern()方法,而python标识符正是由字母、数字和下划线组成。
    2、字符串的连接
        字符串数据类型,是不可变类型,我们都知道,如果我们有了一个字符串,想要修改它,是不可以的,则必须新建一个对象,
        因此不推荐使用“+”连接字符串,而推荐大家采用join()方法
    3、整数驻留
        python会针对整数范围是[-5, 256]的整数启用驻留机制(python认为这些数字时常用数字,放在缓存中节省开销)
	4、在pycharm和黑窗口(iterm)中测试结果不同,具体原因不详
		1)teminal:不触发字符串驻留机制
    	2)pycharm:触发字符串驻留机制
    	
P.S 比较运算符:
    == ->     value的比较
    is,is not 内存地址比较
"""
str1 = "abc"
str2 = "abc"	# 相同字符串的内存地址也相等 -> str1与str2内存地址相等
str3 = "".join(['ab', 'c'])
print(str1, type(str1), id(str1))  # abc  4378617712
print(str2, type(str2), id(str2))  # abc  4378617712
                                        # 结论: str1、str2的地址相等
print(str3, type(str3), id(str3))  # abc  4381017264

"""
在不同场景测试包含[\w\d_]以外的字符时,python字符串驻留机制(python3.8.9)
    1)terminal:不触发字符串驻留机制
    2)pycharm:触发字符串驻留机制
"""

"""1) terminal:
groupiesm@bogon ~ % python3
Python 3.8.9 (default, Feb 18 2022, 07:45:33)
[Clang 13.1.6 (clang-1316.0.21.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> str4='abc%'
>>> str5='abc%'
>>> str4==str5
True
>>> str4 is str5
False
>>>
"""

"""2) pycharm:"""
str4 = 'abc%'
str5 = 'abc%'
print(str4 == str5)  # True 比较value
print(id(str4)) # 4300391152
print(id(str5)) # 4300391152
print(str4 is str5)  # True 比较内存地址

3.3 查询

"""
 @author GroupiesM
 @date 2022/5/23 17:01
 @introduction
 查询方法:
    index(): 查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError
    rindex():查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError
    find():查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1
    rfind():查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回-1
"""
s = 'hello,hello'
print(s.index('lo'))  # 3
print(s.rindex('lo'))  # 9
print(s.find('lo'))  # 3
print(s.rfind('lo'))  # 9

# print(s.index('k'))  #报错 如果查找的子串不存在时,则抛出ValueError
# print(s.rindex('k'))  #报错 如果查找的子串不存在时,则抛出ValueError
print(s.find('k'))  # -1
print(s.rfind('k'))  # -1

3.4 大小写转换

"""
 @author GroupiesM
 @date 2022/6/20 09:34
 @introduction
 大小写转换:
    upper(): 把字符串中所有的字符都转成大写字母
    lower(): 把字符串中所有的字符都转成小写字母
    swapcase(): 把字符串中所有大写字母转成小写字母,把所有小写字母转成大写字母
    capitalsize(): 整个字符串首字母大写,其余字母小写
    title(): 每个单词首字母大写,其余字母小写
"""
s = 'hEllo WoRld'
print(s, id(s))  # hEllo WoRld 4333433968
print(s.upper(), id(s.upper()))  # HELLO WORLD 4333137520
print(s.lower(), id(s.lower()))  # hello world 4333137520
print(s.swapcase(), id(s.swapcase()))  # HeLLO wOrLD 4333137520
print(s.capitalize(), id(s.capitalize()))  # Hello world 4333137520
print(s.title(), id(s.title()))  # Hello World 4333137520

3.5 内容对齐

"""
 @author GroupiesM
 @date 2022/6/20 10:33
 @introduction
 内容对齐:
    center(): 居中对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
    ljust(): 左对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
    rjust(): 右对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
    zfill(): 右对齐,左边用0填充,第1个参数指定宽度,如果设置宽度小于实际宽度则返回原字符串
"""
s = 'hello world'
'''指定填充'''
print(s.center(20, '*'))  # ****hello world*****
print(s.ljust(20, '&'))  # hello world&&&&&&&&&
print(s.rjust(20, '^'))  # ^^^^^^^^^hello world
print(s.zfill(20))  # 000000000hello world

'''不指定填充'''
print(s.center(20))  #    hello world
print(s.ljust(20))  #hello world
print(s.rjust(20))  #         hello world
print(s.zfill(20))  # 000000000hello world

'''指定宽度 < 字符串长度'''
print(s.center(5))  # hello world
print(s.ljust(4))  # hello world
print(s.rjust(3))  # hello world
print(s.zfill(2))  # hello world

3.6 split()-分割

"""
 @author GroupiesM
 @date 2022/6/20 10:44
 @introduction
 split()-分割:
    split(self,sep,maxsplit):从字符串左边开始分割,返回一个列表
        self:字符串本身
        sep:指定分隔符,默认为空格
        maxsplit:指定最大分割次数,分割指定次数后,剩余字符串作为一个整体不再分割
    rsplit():从字符串右边开始分割,返回一个列表(参数相同)
"""

s = 'a1b1c d1e1f g h'
print(s.split())  # ['a1b1c', 'd1e1f', 'g', 'h']
print(s.split(sep='1'))  # ['a', 'b', 'c d', 'e1f']
print(s.split(maxsplit=3))  # ['a', 'b', 'c d', 'e', 'f g h']
print(s.split(sep='1', maxsplit=3))  # ['a', 'b', 'c d', 'e1f g h']

print('----')
print(s.rsplit())  # ['a1b1c', 'd1e1f', 'g', 'h']
print(s.rsplit(sep='1'))  # ['a', 'b', 'c d', 'e', 'f g h']
print(s.rsplit(maxsplit=3))  # ['a1b1c', 'd1e1f', 'g', 'h']
print(s.rsplit(sep='1', maxsplit=3))  # ['a1b', 'c d', 'e', 'f g h']

3.7 判断

"""
 @author GroupiesM
 @date 2022/6/20 11:21
 @introduction
 判断:
    isidentifier(): 合法的变量名(可用作接收变量的变量名)
    isspace(): 全部由空字符串组成(回车、换行、水平制表符)
    isalpha(): 全部由字母组成
    isdecimal(): 全部由十进制的数字组成
    isnumeric(): 全部由数字组成(中文简体、繁体,符号,罗马数字)
    isalnum(): 全部由字母和数字组成
"""
print('---isidentifier() 合法的变量名(可用作接收变量的变量名)---')
print('if'.isidentifier())  # True
print('_b'.isidentifier())  # True
print('张三'.isidentifier())  # True
print('8a'.isidentifier())  # False
print(''.isidentifier())  # False

print('---isspace() 全部由空字符串组成(回车、换行、水平制表符)---')
print(' \r\t\n'.isspace())  # True
print(' \r\t\n0'.isspace())  # False

print('---isalpha() 全部由字母组成---')
print('abc'.isalpha())  # True
print('张三'.isalpha())  # True
print('张三1'.isalpha())  # False

print('---isdecimal(): 全部由十进制的数字组成---')
print('123'.isdecimal())  # True
print('12三'.isdecimal())  # True
print('123.4'.isdecimal())  # False
print('123 '.isdecimal())  # False

print('---isnumeric(): 全部由数字组成(中文简体、繁体,符号,罗马数字)---')
print('12'.isnumeric())  # True
print('12②贰Ⅱ'.isnumeric())  # True
print('1two'.isnumeric())  # False

print('---isalnum(): 全部由字母和数字组成---')
print('张三8'.isalnum())  # True
print('张三8 '.isalnum())  # False

3.8 替换

"""
 @author GroupiesM
 @date 2022/6/20 12:04
 @introduction
 替换:
    replace(String old,String new):
    replace(String old,String new,Integer count):
        self: 默认字符串本身
        1.old: 替换前的字符串
        2.new: 替换后的字符串
        3.count: 最大替换次数,(可省略参数)
"""
s = '12 12 12'
print(s.replace(' ', '\r\n', 1))
'''
12
12 12
'''
print('---')
print(s.replace(' ', '\r\n'))
'''
12
12
12
'''

3.9 字符串合并

"""
 @author GroupiesM
 @date 2022/6/20 12:12
 @introduction
 合并:
    join(): 将列表或元组中的字符串合并成一个字符串,列表或元组的元素必须都是字符串
"""
lst =['1 ','2 ','345']
print(''.join(lst)) # 1 2 345

lst =['1 ','2 ',345]
print(''.join(lst)) # TypeError: sequence item 2: expected str instance, int found

3.10 比较

"""
 @author GroupiesM
 @date 2022/6/21 16:57
 @introduction
 比较:
    运算符:>,>=,<,<=,==,!=
        比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,
        依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的
        比较结果,两个字符串中所有的后续字符将不再被比较
    比较原理:
        两个字符进行比较,比较的是其 ASCII码值
        通过内置函数ord(字符),可以获取字符对应的 ASCII码值(数字)
        通过内置函数chr(数字),可以获取数字对应的 字符
"""
'''>'''
print("apple" > "app")  # True
print('a' > '张')  # False
print(ord('a'))  # 97
print(ord('张'))  # 24352
print(chr(97))  # a

'''
==与is的区别
    ==比较的是value
    is比较的是id是否相等(内存地址)
'''
a = 'ab'
b = "".join(['a', 'b'])

'''a与b的 值、内存地址'''
print(a, id(a)) # ab 4375883376
print(b, id(b)) # ab 4377252400

print(a == b)  # True :a与b值相等
print(a is b)  # False :a与b内存地址不相等

3.11 切片

"""
 @author GroupiesM
 @date 2022/6/22 11:28
 @introduction
 切片:
    1.字符串是不可变类型,不具备增、删、改等操作
    2.字符串是不可变类型,切片操作将产生新的对象

 假设有字符串 str = 'hello,python',已知str长度为11
    0   1   2   3  4  5  6  7  8  9  10  11  [正向索引]
    h   e   l   l  o  ,  p  y  t  h  o   n
   -11 -10 -9  -8 -7 -6 -5 -4 -3 -2 -1       [反向索引] 了解即可
 切片语法1:newStr = str[起始(x):结束(y):步长(s)]
    其中x,y为任意整数,表示索引位置
    其中s为任意整数,表示步长(每次取字符间隔几个位置)
    1. 起始(x)可以省略不写,不写则取默认值 0;例如 str[:5] <=> str[0:5]
    2. 结束(y)可以省略不写,不写则取默认值 字符串结尾位置; 例如str[6:] <=> str[6:11]
    3. 步长(s)可以省略不写,不写则取默认值 1; 例如str[:5:] <=> str[:5:1]
    4. 若 起始(x)>结束(y),生成新的字符串为空字符串 ''
    5. 若 0 < 起始(x) < 结束(y),则按照 正向索引 进行切片操作
    6. 若 起始(x) < 结束(y) < 0,则按照 反向索引 进行切片操作。基本没有使用场景,了解即可
    7. 若 s<0,则字符串反向切片
"""
str = 'hello,python'
s1 = str[:5]  # str[:5] <=> str[0:5] 两种写法等价
print('s1', s1)  # hello

s2 = str[6:]  # str[6:] <=> str[6:11] 两种写法等价
print('s2', s2)  # python

s3 = str[:]  # str[:] <=> str[0:11] 两种写法等价
print('s3', s3)  # hello,python

s4 = str[0:5:]  # str[0:5:] <=> str[0:5:1] 两种写法等价
print('s4', s4)  # hello

s5 = str[-5:-1]
print('s5', s5)  # s5 ytho

s6 = str[0:5:1]
print('s6', s6)  # hlo

s7 = str[-15:-1]  # s<0,反向切片
print('s7', s7)  # nohtyp,olleh

3.12 字符串编解码

"""
 @author GroupiesM
 @date 2022/6/27 16:48
 @introduction
 字符串编解码:
    目的:用于网络中的数据传输(byte字节传输)

    encode(String encoding):编码,将字符串转换为二进制数据(bytes)
    decode(String encoding):解码,将bytes类型的数据转换为字符串类型

    P.S
        1.编码方式:常见编码方式有 GBK、UTF-8
        2.乱码最常见的原因就是编解码不一致
"""
s = '将bytes类型的数据转换为字符串类型'

# 编码 - b'\xbd\xabbytes\xc0\xe0\xd0\xcd\xb5\xc4\xca\xfd\xbe\xdd\xd7\xaa\xbb\xbb\xce\xaa\xd7\xd6\xb7\xfb\xb4\xae\xc0\xe0\xd0\xcd'
g_encode = s.encode('GBK')
g_encode = s.encode(encoding='GBK')
print(g_encode)

# 解码 - 将bytes类型的数据转换为字符串类型
g_decode = g_encode.decode('GBK')
g_decode = g_encode.decode(encoding='GBK')
print(g_decode)

22/06/28

M

你可能感兴趣的:(六,python,python,开发语言)