2.方法

0 阅读13分钟

对象

在Python中,万物皆对象,每一个对象,都是独立的、独一无二的个体

image.png 每1个对象都有自己的唯一标识(简称id,类似于人的身份证),可以通过 id 函数获取对象的id

image.png 如果2个对象的id相同,说明它们其实是同1个对象

可变类型,不可变类型

list 是可变类型,int,float,bool,str是不可变类型,这里说的可变、不可变指的是对象,并不是指变量,变量是肯定可以变的。

方法

方法是一种需要通过对象来调用的特殊函数(function) 方法的使用格式是:对象.方法名(参数)

list 常用方法

1. 查询index

  • s.index(x) 查询元素 x 在 s 中的最小索引(从左往右搜索) 如果元素 x 不在 s 中,会报错(ValueError)

  • s.index(x, i, j) 在 [i, j) 范围内搜索(包头不包尾)

  • s.index(x, i),在 [i, len(s)) 范围内搜索(即从索引 i 一直搜到末尾)

2. 查询 - count

s.count(x) 统计 s 中有多少个元素 x

3.添加 - append

添加 - s.append(x):添加元素 x 到 s 的尾部,注意一点就是append操作,新生成的对象和旧的对象其实还是一个对象 s.append(x) 等价于 s[len(s):] = [x]

4.插入 - insert

  • s.insert(i, x):将元素 x 插入到索引为 i 的位置,首先 i 的正常合理范围是 [-len(s), len(s) - 1],如果 i < -len(s),代表往头部插入, 如果 i > len(s) - 1,代表往尾部插入,跟 s.append(x) 效果是一样的
  • s.insert(i, x) 等价于 s[i:i] = [x]

5.添加 - extend

s.extend(t):将可迭代对象t中的所有元素添加到尾部

s = [55]

# extend 可以一次性将另一个列表里的元素全部追加进来
s.extend([44, 33])

# extend 后面只要是“可迭代对象”就行,range(20, 0, -10) 会生成 20 和 10
s.extend(range(20, 0, -10))

# [55, 44, 33, 20, 10]
print(s)

注意append和extend的区别

注意的是append要求是只能加单个,不论你是数字,还是list都当成一个整体加进去,而extend加的是可迭代对象,比方说1数字不是可迭代对象,就不能用extend,要写也只能写成extend([1]),他是把可迭代对象的对象一个一个捞出来放到原对象中

s1 = [55, 44, 33]
# extend 会把列表 [22, 11] 拆开,把里面的元素逐个加进去
s1.extend([22, 11])

# [55, 44, 33, 22, 11]
print(s1)

s2 = s1
# append 会把列表 [22, 11] 当成“一个独立的对象”,整个塞到末尾
s2.append([22, 11])
# [55, 44, 33, [22, 11]] (形成了嵌套列表)
print(s2)

6.删除 - pop

s.pop(i):删除并返回索引为i的元素,如果不写的话就是删除尾部元素。i必须要合理,如果空列表,调这个方法要报错(IndexError: pop from empty list),越界也会报IndexError错误。\

s.pop()如果用切片可以用s[len(s) - 1:] = [] 或者 s[-1:] = [] \

如果s是空列表,p s.pop() 会报错(IndexError),s[len(s) - 1:] = []、s[-1:] = [] 并不会报错

s.pop(i) 等价于 s[i:i + 1] = [],如果i越界了,s.pop(i) 会报错(IndexError),s[i:i + 1] = [] 并不会报错

7.删除 - remove

s.remove(x),删除1个元素x(从左往右搜索),如果元素x不在列表中,会报错(ValueError)

s = [55, 44, 33, 44, 44]

# 从左往右找,删除了第一个遇到的 44,后面的保留
s.remove(44)

# [55, 33, 44, 44]
print(s)

# ValueError: 66 is not in list (如果要删除的元素不存在,程序会直接报错)
s.remove(66)

8.del删除

使用关键字del实现删除功能(del是delete的简写)

s = [55, 44, 33, 22, 11]

# 1. 删除单个指定索引的元素
del s[0]
# [44, 33, 22, 11]
print(s)

# 2. 结合切片批量删除(这里步长为2,即删掉索引为 0 和 2 的元素 44 和 22)
del s[::2]
# [33, 11]
print(s)

# 3. 注意:如果像下面这样删除单个不存在的越界索引,会直接报错
# IndexError: list assignment index out of range
# del s[100]

# 4. 但是:如果使用切片的形式删除越界范围,则不会报错(只是相当于什么都没删)
del s[100:]

del s[i:j] 等价于 s[i:j] = []

s = [55, 44, 33, 22, 11]

# 把切片范围内的元素赋值为空列表,就相当于把它们删除了
# 这里的效果完全等同于执行 del s[1:4]
s[1:4] = []

# 最终剩下的结果
# [55, 11]
print(s)

几个区别

  1. del s[:] 和 del s del s[:] 是切片删除,它的作用是:清空列表里的所有元素。此时变量 s 依然存在,只是变成了一个空列表 []。
    del s 是删除整个变量,它的作用是:把变量 s 这个名字从内存中彻底抹除。
s = [55, 44, 33, 22, 11]

# 1. del s[:]
del s[:]
print(s)  # []

del s
# 因为变量 s 已经被删除了,所以再试图打印它会直接报错:
# NameError: name 's' is not defined (变量名没定义)
print(s)


# 3. 既然前面的 s 已经被抹除了,你可以随时重新定义它指向别的东西
s = 55
print(s)  # 55

2.s[:] = [] 和 s = [] 的区别
s[:] = []这种写法,s1 从头到尾都指向着同一个列表对象(原地清空)。
s = [] 最后重新指向了 1 个新的空列表对象(和原来的对象不是同一个对象,他们的id不一样)。\

s1 = [55, 44, 33, 22, 11]

print(id(s1))  # 假设地址是:2224932534848

# 把原列表里的内容全部掏空
s1[:] = []

# 因为还是原来的那个列表,所以内存地址完全没变!
print(id(s1))  # 依然是:2224932534848

print(s1)  # []
s2 = [55, 44, 33, 22, 11]

print(id(s2)) # 假设地址是:2385144540480
# 这不是清空,而是直接让 s2 绑定到一个全新创建的空列表上
s2 = []
# 因为换了一个新列表,所以内存地址彻底改变了!
print(id(s2))  # 变成了新地址:2387353328384
print(s2)  # []

9.删除clear

s.clear(),删除所有元素,等价于del s[:]

str 常用方法

1.查询index和rindex

s.index(x, i, j) 从左往右查找,查找在[i, j)范围内搜索,如果有多个,获取的是最小索引,如果是一个都没有,则会报错(ValueError).

s.rindex(x, i, j) 从右往左查找,查找在[i, j)范围内搜索,如果有多个,获取的是最小索引,如果是一个都没有,则会报错(ValueError).

上面的两个方法如果i,j都不写的话,则就是查找整个字符串

2. 查询 - find和rfind

和上面的index,rindex方法类似,差别在于index,rindex如果找不到指定的子串,程序会直接抛出报错ValueError),导致程序崩溃中断,而find和rfind找不到会返回 -1

3. 查询 - count 方法

s.count(x) 统计 s 中有多少个子串 x(核心注意:子串之间是不重叠计算的)

s.count(x, i) 在 [i, len(s)) 范围内统计

s.count(x, i, j) 在 [i, j) 范围内统计(包头不包尾)

4. 查询 - endswith

s.endswith(x, i, j)

p 在[i, j)范围内查看

4. 查询 - startswith

用于检查字符串是否以特定的子串开头。

  • s.startswith(x) :查看 s 是否以子串 x 开头。
  • s.startswith(x, i) :在 [i, len(s)) 范围内查看。
  • s.startswith(x, i, j) :在 [i, j) 范围内查看(包头不包尾)
s = 'MJ666MJ666'

# 基础检查
print(s.startswith('MJ'))       # True
print(s.startswith('66'))       # False

# 指定范围检查
print(s.startswith('MJ', 5))    # True (从索引 5 开始,即后半段 'MJ666')
print(s.startswith('MJ', 2, 8)) # False (在 '666MJ6' 范围内查找,并非以 'MJ' 开头)

# 特殊情况
print(s.startswith(''))         # True (任何字符串都默认以空字符串开头)
print(s.startswith(s))          # True (自身总是以自身开头)

5. 大小写处理

  • s.upper() :返回 s 的全大写形式。
  • s.lower() :返回 s 的全小写形式。
  • s.swapcase() :大小写反转(大写变小写,小写变大写)。
  • s.title() :标题化,即每个单词的首字符变大写。
  • s.capitalize() :首字母大写,其余所有字符强制变小写
# 全大写与全小写
s1 = 'jack'
print(s1.upper())       # JACK

s2 = 'JACK'
print(s2.lower())       # jack

# 大小写反转
s3 = 'Hello World'
print(s3.swapcase())    # hELLO wORLD

# 首字母大写 (title vs capitalize)
s4 = 'my name is jack'
print(s4.title())       # My Name Is Jack (每个单词首字母都大写了)
print(s4.capitalize())  # My name is jack (仅整个字符串的第一个字母大写)

# capitalize 会将后面原本的大写强行转为小写
s5 = 'hELLO WorLD'
print(s5.capitalize())  # Hello world 

判断大小写

  • s.isupper() :判断 s 是否为全大写。
  • s.islower() :判断 s 是否为全小写。
print('JACK'.isupper())  # True
print('jAcK'.isupper())  # False

print('jack'.islower())  # True
print('jAcK'.islower())  # False

6. 字符串格式化

用于将变量动态插入到字符串中。从 Python 3.6 开始,推荐使用更简便的 f-string 语法。

  • 传统用法s.format()
  • 现代用法:在字符串前加 f 或 F 前缀。
name = 'MJ'
age = 18

# 现代推荐写法 (f-string)
print(f'My name is {name}, age is {age}')
# 输出: My name is MJ, age is 18

# 传统写法 (.format)
print('My name is {}, age is {}'.format(name, age))
# 输出: My name is MJ, age is 18

7.空格与特定字符剔除:strip 系列

用于剥离字符串边缘的冗余字符。

剔除空格(默认行为)

  • s.strip() :删除左右两端的空格字符。
  • s.lstrip() :只删除左边的空格(left)。
  • s.rstrip() :只删除右边的空格(right)。
s = ' 1 2  '

# 拼接 '0' 是为了在终端里能直观看到边缘空格被删除的情况
print(f'0{s}0')          # 0 1 2  0  (原状)
print(f'0{s.strip()}0')  # 01 20     (左右两端的空格都被删除了,中间的保留)
print(f'0{s.lstrip()}0') # 01 2  0   (只删了左边)
print(f'0{s.rstrip()}0') # 0 1 20    (只删了右边)

剔除指定字符集

  • s.strip(x) :删除左右两端的任意属于 x 集合内的字符。  (注意:这里的 x 是一个字符集合,剔除时不讲究顺序,只要边缘字符在这个集合里就会被删,直到遇到一个不在集合里的字符为止。)
s_url = 'www.520it.com'

# 只要边缘的字符属于 '5', 'm', 'w', '.', 'c', 't' 中的任何一个,就会被剔除掉
# 左侧:'w', '.', '5' 被剔除,停在 '2'
# 右侧:'m' 被剔除,停在 'o'(因为 'o' 不在集合里)
print(s_url.strip('5mw.ct'))   # 结果:20it.co

# 单侧处理同理
print(s_url.lstrip('5mw.ct'))  # 结果:20it.com
print(s_url.rstrip('5mw.ct'))  # 结果:www.520it.co

8.拼接:join

用于将一个“可迭代对象”中的多个字符串,使用指定的分隔符连接成一个新的字符串。

  • s.join(x)x 是一个可迭代对象(例如列表、元组等)。
  • 注意x 中的所有元素必须都是字符串 (str) 类型,否则会报错。s 将作为拼接时的分隔符。
s1 = '+=+'
data = ['red', 'blue', 'green']
s2 = s1.join(data)

print(s1, s2, sep='\n')
# 输出:
# +=+
# red+=+blue+=+green

# 常用的快速拼接写法
print('+'.join(['1', '2', '3']))
# 输出: 1+2+3

9.切割:split

用于将一个字符串按照指定的分隔符拆分成多个子串,并以列表 (list)  的形式返回结果。

  • s.split(x) :以 x 作为分隔符将 s 切割出若干个子串。
  • s.split(x, k)k 是最大切割次数。当 k 为负数时,表示不限制切割次数(这是默认行为)。
s = '192.168.20.48'

# 默认全部切割
print(s.split('.'))  # ['192', '168', '20', '48']

# 以普通数字字符作为分隔符,分隔符本身会被消耗掉
print(s.split('2'))  # ['19', '.168.', '0.48']
print(s.split('8'))  # ['192.16', '.20.4', '']

# 限制最大切割次数 k
for i in range(5):
    print(i, s.split('.', i))
# 0 ['192.168.20.48']       (切0次,原样包裹在一个列表里返回)
# 1 ['192', '168.20.48']    (切1次,分成两块)
# 2 ['192', '168', '20.48']
# 3 ['192', '168', '20', '48']
# 4 ['192', '168', '20', '48'] (最多只能切3次,传4也没影响了)

# 负数 k 表示不限制次数
print(s.split('.', -2))  # ['192', '168', '20', '48']

特殊切割场景说明

  • 如果不传分隔符,默认以所有连续的空白字符(空格、换行、制表符等)为分隔符。
  • 不能传入空字符串 '' 作为分隔符,否则会引发 ValueError 报错。
  • 如果想把字符串中的“每一个字符”都单独切开,不要用 split,直接使用 list() 转换即可。
# 没有传入分隔符,且原字符串没有空白字符,因此整个作为一个元素返回
print('mj666'.split())      # ['mj666']

print('mj666'.split('66'))  # ['mj', '6']
print('mj666'.split('8'))   # ['mj666'] (找不到指定的分隔符,原样返回)

# 报错:分隔符不能为空!
# print('mj666'.split(''))  # ValueError: empty separator

# 正确的“逐字符打散”姿势:使用 list()
print(list('mj666'))        # ['m', 'j', '6', '6', '6']

10.补零填充:zfill

主要用于数字字符串的格式化对齐操作(例如生成固定位数的流水号)。

  • s.zfill(x) :用字符 0 填充到 s 的左边,直到字符串的总长度达到 x
  • 智能处理符号:如果字符串以 + 或 - 开头,0 会被智能地填充在符号和数字之间。
s1 = '45'
s2 = s1.zfill(5)
print(s1, s2)               # 45 00045

# 智能识别正负号
print('+45'.zfill(5))       # +0045
print('-45'.zfill(5))       # -0045

# 如果原长度已经达到或超过 x,则不会做任何事,原样返回
print('12345'.zfill(3))     # 12345

# 实际应用对比:生成固定位数的序列号
# 方式1:传统 % 格式化
for i in range(5):
    print('%03d' % i)

# 方式2:使用 zfill (需要先将数字转为 str)
for i in range(5):
    print(str(i).zfill(3))
    
# 上述两种方式输出结果完全一致:
# 000
# 001
# 002
# 003
# 004

11. 替换:replace

用于将字符串中的特定子串替换为新的子串。

  • s.replace(x, y) :将所有的子串 x 替换为字符串 y。  (技巧:当 y 为空串 '' 时,实际上就相当于删除了所有的子串 x)
  • s.replace(x, y, k)k 是最大替换次数。当 k 为负数时,不限制替换次数(这是默认行为)。
s1 = '192.168.1.20'

# 全局替换所有匹配项
s2 = s1.replace('.', '_')
print(s1, s2, sep='\n')
# 192.168.1.20
# 192_168_1_20

# 限制替换次数(只替换前两次遇到的 '.')
print(s1.replace('.', '_', 2))
# 192_168_1.20

# 常规替换其他子串
print('mj666'.replace('666', '168')) # mj168

# 特殊技巧:替换为空串相当于"删除"操作
print('www.00700.com'.replace('0', '')) # www.7.com

# 偏门现象:如果被替换项是空串,它会在每个字符的间隙都插入新字符
print('mj666'.replace('', '_')) # _m_j_6_6_6_

12.str的常用方法 - 删除

删除前缀

s.removeprefix(x),删除前缀 x,如果 s 中存在前缀 x,底层逻辑等价于切片操作:s[len(x):]

删除后缀

s.removesuffix(x),删除后缀 x,如果 s 中存在后缀 x,底层逻辑等价于切片操作:s[:-len(x)]

s1 = 'www.520it.com'

# 正常删除确实存在的前缀
s2 = s1.removeprefix('www.')
print(s1, s2, sep='\n')
# www.520it.com
# 520it.com

# 尝试删除一个不是前缀的子串('520it' 在中间)
# 结果:什么都不会删,原样返回
print(s1.removeprefix('520it'))
# www.520it.com

# 等价的切片写法展示(原理演示)
print(s1[len('www.'):])
# 520it.com
s1 = 'www.520it.com'

# 正常删除确实存在的后缀
s2 = s1.removesuffix('.com')
print(s1, s2, sep='\n')
# www.520it.com
# www.520it

# 尝试删除一个不是后缀的子串
# 结果:同样什么都不会删,原样返回
print(s1.removesuffix('520it'))
# www.520it.com

# 等价的切片写法展示(原理演示)
print(s1[:-len('.com')])
# www.520it