Python基础:字符串索引与切片操作完全指南
一、开篇:字符串是一串带编号的字符
想象一下酒店的房间走廊------每个房间门上都贴着一个编号,第一个房间是0号,第二个是1号,以此类推。Python中的字符串就像这个走廊,每个字符是一个房间,而索引就是房间号。
在Python中,想要操作字符串的任意部分:提取子串、反转字符串、隔位取值、批量截取文本 ,全部依靠索引和切片实现。
这是Python字符串处理最核心、最高频的基础技能,零基础必掌握,吃透它能彻底解决90%的文本处理需求!
二、索引基础:单个字符的精准访问
索引的作用:精准获取字符串中单个字符 ,分为正索引 和负索引两种模式。
2.1 正索引:从左往右,从0开始
计算机通用规则:索引从0开始计数,第n个字符,对应索引为n-1。
python
text = 'Python'
# 字符对应关系
# 字符: P y t h o n
# 正索引:0 1 2 3 4 5
print(text[0]) # P(第一个字符)
print(text[1]) # y
print(text[2]) # t
print(text[5]) # n(最后一个字符)
# print(text[6]) # IndexError: string index out of range 索引越界报错
新手口诀:正数从左数,首位是0,依次递增。
2.2 负索引:从右往左,从-1开始
Python独有便捷特性,无需计算字符串长度,直接从末尾取值,日常开发高频使用!
python
text = 'Python'
# 字符对应关系
# 字符: P y t h o n
# 负索引:-6 -5 -4 -3 -2 -1
print(text[-1]) # n(倒数第一个,最后一位)
print(text[-2]) # o(倒数第二个)
print(text[-3]) # h(倒数第三个)
print(text[-6]) # P(倒数第六个,第一位)
# print(text[-7]) # IndexError 索引越界报错
新手口诀:负数从右数,末位是-1,依次递减。
负索引实战场景(开发常用)
python
# 1. 获取文件扩展名
filename = 'report_2024.pdf'
extension = filename[filename.rfind('.'):]
print(extension) # .pdf
# 2. 判断文件后缀
def has_extension(filename, ext):
"""检查文件是否为指定后缀"""
return filename[-len(ext):] == ext
print(has_extension('data.csv', '.csv')) # True
print(has_extension('data.json', '.csv')) # False
# 3. 判断路径结尾符号
path = '/home/user/documents/'
if path[-1] == '/':
print('路径以/结尾')
2.3 索引越界问题与解决方案
索引取值时,超出字符串有效范围,会直接抛出IndexError 报错,程序终止。
报错演示
python
text = 'Hello'
try:
print(text[10])
except IndexError as e:
print(f'索引越界:{e}')
print(f'字符串长度:{len(text)},有效索引范围:-{len(text)} ~ {len(text)-1}')
安全取值封装(生产可用)
python
def safe_get_char(text, index):
"""安全获取索引字符,越界不报错,返回None"""
if -len(text) <= index < len(text):
return text[index]
return None
text = 'Python'
print(safe_get_char(text, 0)) # P
print(safe_get_char(text, 100)) # None(越界容错)
三、切片基础:截取任意子串
如果说索引 是取单个字符,那切片就是取一段字符,是字符串批量处理的核心!
3.1 切片标准语法
语法格式 :text[start:stop:step]
-
start :起始索引(包含该位置)
-
stop :结束索引(不包含该位置,核心易错点)
-
step:取值步长,默认=1(可省略)
python
text = 'Python编程'
# 索引:0 1 2 3 4 5 6 7
# 截取0~5索引字符(不包含6)
print(text[0:6]) # Python
# 截取6~7索引字符
print(text[6:8]) # 编程
记忆技巧:text[a:b] 截取的字符数量 = b - a,完美规避stop不包含的坑!
3.2 省略参数的极简写法(高频)
切片三个参数均可省略,适配不同截取场景,代码极度简洁!
python
text = 'Python'
# 1. 省略start:从字符串开头截取
print(text[:3]) # Pyt
# 2. 省略stop:截取到字符串末尾
print(text[3:]) # hon
# 3. start、stop都省略:复制整个字符串
print(text[:]) # Python
# 4. 负索引切片组合使用
print(text[-3:]) # hon(截取最后3个字符)
print(text[:-2]) # Pyth(删除最后2个字符)
实战案例:文件名、URL解析
python
# 去除文件扩展名
def get_filename_without_extension(filename):
dot_index = filename.rfind('.')
return filename[:dot_index] if dot_index != -1 else filename
print(get_filename_without_extension('document.txt')) # document
print(get_filename_without_extension('data')) # data
# 提取URL域名
url = 'https://www.example.com/path/page.html'
start_idx = url.index('//') + 2
end_idx = url.index('/', start_idx)
domain = url[start_idx:end_idx]
print(domain) # www.example.com
3.3 带步长切片(隔位取值、字符串反转)
步长控制取值间隔,正步长正向取值,负步长反向取值。
python
text = 'Python编程'
# 步长2:隔1个取1个
print(text[::2]) # Pto编
# 步长3:隔2个取1个
print(text[::3]) # Ph程
# 从索引1开始,步长2
print(text[1::2]) # yhn程
# 负步长:字符串反转(Python神级写法)
print(text[::-1]) # 程编nohtyP
print(text[::-2]) # 程nhy
实战:判断回文字符串
python
def is_palindrome(text):
"""判断字符串是否为回文(正读反读一致)"""
# 统一小写、去除空格
clean_text = text.lower().replace(' ', '')
return clean_text == clean_text[::-1]
print(is_palindrome('racecar')) # True
print(is_palindrome('A man a plan a canal Panama')) # True
print(is_palindrome('hello')) # False
3.4 切片完整图解对照表
plain
字符串: P y t h o n 编 程
正索引: 0 1 2 3 4 5 6 7
负索引:-8 -7 -6 -5 -4 -3 -2 -1
text[0:4] = 'Pyth' 取 0,1,2,3
text[4:] = 'on编程' 取 4,5,6,7
text[:4] = 'Pyth' 取 0,1,2,3
text[2:6] = 'thon' 取 2,3,4,5
text[-3:] = 'n编程' 取 5,6,7
text[1:-1] = 'ython编' 取 1~6
text[::2] = 'Pto编' 隔位取值
text[::-1] = '程编nohtyP' 字符串反转
四、切片高级用法(生产必备)
4.1 切片越界不报错(核心特性)
索引越界直接报错,切片越界自动容错,这是切片最友好的特性!
python
text = 'Python'
# 索引越界:直接报错
# print(text[100])
# 切片越界:自动适配有效范围,不报错
print(text[0:100]) # Python(超长stop自动截断)
print(text[100:]) # 空字符串(start超出范围)
print(text[-100:3]) # Pyt(前置start自动归0)
4.2 切片实现字符串删除、替换、插入
字符串不可变,所有修改本质是切片拼接生成新字符串。
python
text = 'Hello, World!'
# 1. 截取删除前6个字符
new_text1 = text[7:]
print(new_text1) # World!
# 2. 替换中间指定内容
new_text2 = text[:7] + 'Python' + text[12:]
print(new_text2) # Hello, Python!
# 3. 插入字符
text3 = 'HelloWorld'
new_text3 = text3[:5] + ' ' + text3[5:]
print(new_text3) # Hello World
# 4. 删除末尾字符
text4 = 'Hello!'
new_text4 = text4[:-1]
print(new_text4) # Hello
4.3 切片实现文本清理、文本截断
python
# 1. 自定义去除首尾空白字符
def remove_whitespace(text):
start = 0
end = len(text)
while start < end and text[start].isspace():
start += 1
while end > start and text[end - 1].isspace():
end -= 1
return text[start:end]
print(repr(remove_whitespace(' hello '))) # 'hello'
# 2. 长文本智能截断
def truncate_text(text, max_length, suffix='...'):
if len(text) <= max_length:
return text
return text[:max_length - len(suffix)] + suffix
print(truncate_text('这是一段很长的文本内容需要被截断', 10))
# 这是一段很长...
4.4 切片实现文本分页
python
def paginate_text(text, page_size):
"""将长文本按指定长度分页"""
return [text[i:i+page_size] for i in range(0, len(text), page_size)]
long_text = 'Python编程语言是一门强大而优雅的语言,适合各种开发场景。'
pages = paginate_text(long_text, 10)
for idx, page in enumerate(pages, 1):
print(f'第{idx}页:{page}')
五、切片性能特性(进阶优化)
5.1 切片会生成新字符串
Python字符串不可变,所有切片操作都会创建新内存地址的字符串,而非引用原数据。
python
text = 'Python'
slice_text = text[0:3]
print(id(text)) # 原字符串内存地址
print(id(slice_text)) # 新字符串内存地址(完全不同)
5.2 大小文本优化建议
-
小字符串:切片几乎无性能损耗,随意使用
-
大文本/文件内容:避免频繁重复切片,会产生大量临时对象,占用内存
-
单字符获取 :优先用索引
text[0],而非切片text[0:1],效率更高
python
# 高效大文本处理:按块一次性切片
def process_text(text, block_size=100):
for i in range(0, len(text), block_size):
block = text[i:i+block_size]
# 业务处理逻辑
pass
六、实战落地:切片高频业务场景
6.1 解析日期字符串
python
date_str = '2024-05-30'
year = date_str[:4]
month = date_str[5:7]
day = date_str[8:10]
print(f'{year}年{month}月{day}日') # 2024年05月30日
6.2 解析固定格式日志
python
# 日志格式:8位日期+6位时间+4位等级+日志消息
log_entry = '20240530143000INFO用户登录成功'
timestamp = log_entry[:14]
level = log_entry[14:18]
message = log_entry[18:]
print(f'时间:{timestamp}')
print(f'等级:{level}')
print(f'消息:{message}')
6.3 手机号/身份证/银行卡脱敏
python
def mask_private_text(text, visible=4, mask='*'):
"""隐私数据脱敏,保留后N位"""
if len(text) <= visible:
return text
return mask * (len(text)-visible) + text[-visible:]
print(mask_private_text('13812345678', 4)) # *******5678
print(mask_private_text('110101199001011234', 4)) # **************1234
print(mask_private_text('6222021234567890', 4)) # ************7890
6.4 字符串轮转
python
def rotate_string(text, n):
"""字符串向左轮转n位,负数向右轮转"""
if not text:
return text
n %= len(text) # 兼容n大于字符串长度的情况
return text[n:] + text[:n]
text = 'Python'
print(rotate_string(text, 1)) # ythonP
print(rotate_string(text, 2)) # thonPy
print(rotate_string(text, -1)) # nPytho
七、新手高频错误汇总
7.1 混淆索引与切片
python
text = 'Hello'
# 索引:返回单个字符,越界报错
print(text[0]) # H
# text[10] 直接报错
# 切片:返回子串,越界不报错
print(text[0:1]) # H
print(text[10:20]) # 空字符串
7.2 步长正负与起止索引不匹配
python
text = 'Python'
# 正向步长:start < stop 才有结果
print(text[0:4:1]) # Pyth(正常)
print(text[4:0:1]) # 空字符串(错误)
# 反向步长:start > stop 才有结果
print(text[4:0:-1]) # ohty(正常)
print(text[0:4:-1]) # 空字符串(错误)
# 万能反转写法(无需考虑索引)
print(text[::-1]) # nohtyP
八、全文总结
核心知识点复盘:
-
索引:正索引从0开始,负索引从-1开始,越界直接报错,用于取单个字符
-
切片语法 :
[start:stop:step],含start、不含stop,可省略任意参数 -
核心技巧 :
[::-1]实现字符串反转,切片越界自动容错 -
高阶用法:切片可实现字符串增删改、文本分页、数据脱敏、日志解析
-
性能注意:切片生成新字符串,大文本避免频繁切片