🕐 预计用时:2-3 小时 | 🎯 今日目标:掌握字符串的索引、切片、格式化和常用方法
字符串就是一串文本数据,用引号包裹起来。
你可以把字符串想象成一个珠子手链 📿——每一颗珠子就是一个字符,整条手链就是一个字符串。
# 这些都是字符串name = "小明"greeting = '你好'address = "北京市海淀区中关村大街1号"empty = "" # 空字符串,什么都没有的"空手链"# 单引号和双引号都可以s1 = 'hello's2 = "hello"print(s1 == s2) # True,效果完全一样True💡 单引号 vs 双引号:就像 T恤和衬衫,穿哪个都行。但当字符串里有引号时,就需要"内外搭配"——外面用双引号,里面就用单引号,反之亦然。
# 引号的"内外搭配"print("小明说:'你好!'") # 外双内单 ✅print('小明说:"你好!"') # 外单内双 ✅# print("小明说:"你好!"") # ❌ 报错!引号冲突了小明说:'你好!'小明说:"你好!"name = "Python"print(len(name)) # 数一下有几个字符sentence = "我爱编程"print(len(sentence))empty = ""print(len(empty))640字符串就像一行文字,每个字符都有自己的位置
想象你有一个书架,上面放了一排书。从左边开始数,第1本是0号,第2本是1号……这就是索引。
Python 的索引从 0 开始!这是新手最容易踩的坑。
s = "Python"# 正向索引(从左到右,从0开始)# P y t h o n# 0 1 2 3 4 5# 反向索引(从右到左,从-1开始)# P y t h o n# -6 -5 -4 -3 -2 -1s = "Python"# 用正向索引取字符print(s[0]) # 第1个字符print(s[1]) # 第2个字符print(s[5]) # 第6个字符# 用反向索引取字符print(s[-1]) # 最后一个字符print(s[-2]) # 倒数第2个字符print(s[-6]) # 第1个字符(和s[0]一样)PynnoP索引就像书架上每本书的编号——从0开始数
🤔 为什么从 0 开始?这是编程界的"传统"。就像楼层:在中国1楼是地面层,在英国0楼才是地面层。Python 选择了"0楼"方案。记住就好,不用纠结为什么!
s = "Python"# print(s[10]) # ❌ IndexError: 字符串索引超出范围# 安全的做法:先检查长度if len(s) > 10: print(s[10])else: print("字符串没那么长!")字符串没那么长!切片就像切面包——你可以从任意位置开始切,到任意位置结束,还能决定切多厚(步长)。
# 切片语法:s[start:end:step]# start: 从哪里开始切(包含)# end: 切到哪里停(不包含!)# step: 每隔几个切一刀(默认为1)s = "Hello, Python!"# 从索引1到索引4(不包含4)print(s[1:4]) # ell# 从头开始切到索引5(不包含5)print(s[:5]) # Hello# 从索引7切到末尾print(s[7:]) # Python!# 完整复制print(s[:]) # Hello, Python!ellHelloPython!Hello, Python!💡 记住:切片是"左闭右开"!s[1:4] 包含索引1、2、3,但不包含索引4。就像切面包:刀从位置1切入,到位置4切出——刀痕在4的位置,但那片面包是从1到3的。
s = "0123456789"# 每隔1个取一个(默认)print(s[::1]) # 0123456789# 每隔2个取一个print(s[::2]) # 02468# 每隔3个取一个print(s[::3]) # 0369# 从索引1开始,每隔2个取一个print(s[1::2]) # 13579012345678902468036913579s = "Python"# 步长为-1,就是从右往左切print(s[::-1]) # 反转!word = "上海自来水来自海上"print(word[::-1]) # 经典回文nohtyP上海自来水来自海上🎉 s[::-1] 是 Python 反转字符串最优雅的方式!步长为 -1 就是"倒着切面包"。
s[1:4] | ||
s[:3] | ||
s[2:] | ||
s[:] | ||
s[::2] | ||
s[::-1] | ||
s[-3:] |
f-string 是 Python 最好用的字符串格式化方式(Python 3.6+ 才有)。
想象你填表格——表格上有固定的模板,你只需要把空白处填上具体内容。f-string 就是这个"填表格"的过程。
name = "小明"age = 18city = "北京"# f-string:在字符串前加 f,用 {} 填入变量print(f"我叫{name},今年{age}岁,来自{city}")我叫小明,今年18岁,来自北京💡 f-string 的 f 是 "format"(格式化)的缩写。花括号 {} 就是"填空的地方",Python 会自动把变量的值填进去。
price = 25quantity = 3# 花括号里可以直接写表达式print(f"单价:{price}元")print(f"数量:{quantity}个")print(f"总价:{price * quantity}元") # 可以算数!print(f"打折后:{price * quantity * 0.8}元")单价:25元数量:3个总价:75元打折后:60.0元pi = 3.14159265# 保留2位小数print(f"圆周率:{pi:.2f}")# 保留4位小数print(f"圆周率:{pi:.4f}")# 数字补零(宽度5,不足补0)num = 42print(f"编号:{num:05d}") # 00042# 字符串居中、左对齐、右对齐name = "Python"print(f"[{name:^20}]") # 居中,宽度20print(f"[{name:<20}]") # 左对齐print(f"[{name:>20}]") # 右对齐圆周率:3.14圆周率:3.1416编号:00042[ Python ][Python ][ Python]name = "小明"age = 18# 方法1:f-string(推荐!)print(f"我叫{name},今年{age}岁")# 方法2:format() 方法print("我叫{},今年{}岁".format(name, age))# 方法3:% 格式化(老式写法)print("我叫%s,今年%d岁" % (name, age))我叫小明,今年18岁我叫小明,今年18岁我叫小明,今年18岁🏆 统一推荐使用 f-string!最简洁、最直观、性能最好。其他两种了解即可,看到别人代码时能认出来就行。
f-string 让字符串格式化变得简单直观
字符串自带了很多"工具方法",就像瑞士军刀上的各种小工具。
把一串文字按指定分隔符切成列表,就像用剪刀✂️剪绳子。
sentence = "我 爱 Python 编程"# 按空格切割words = sentence.split()print(words)# 指定分隔符data = "苹果,香蕉,橘子,葡萄"fruits = data.split(",")print(fruits)# 限制切割次数s = "a-b-c-d-e"print(s.split("-", 2)) # 只切2次['我', '爱', 'Python', '编程']['苹果', '香蕉', '橘子', '葡萄']['a', 'b', 'c-d-e']把列表里的元素用指定符号连接起来,就像用绳子把珠子串成手链。
words = ["我", "爱", "Python"]# 用空格连接sentence = " ".join(words)print(sentence)# 用逗号连接result = ",".join(words)print(result)# 用箭头连接result = " → ".join(words)print(result)我 爱 Python我,爱,Python我 → 爱 → Python去掉字符串两边的空格、换行符等,就像擦干净脏东西。
s = " Hello, Python! "print(f"[{s}]") # 原样print(f"[{s.strip()}]") # 去两边print(f"[{s.lstrip()}]") # 只去左边print(f"[{s.rstrip()}]") # 只去右边# 也可以去除指定字符s2 = "###Hello###"print(s2.strip("#"))[ Hello, Python! ][Hello, Python!][Hello, Python! ][ Hello, Python!]Hellos = "我爱Java,Java最好用了"# 替换所有匹配的new_s = s.replace("Java", "Python")print(new_s)# 只替换前1个s2 = "aaa-bbb-aaa-bbb"print(s2.replace("aaa", "xxx", 1))我爱Python,Python最好用了xxx-bbb-aaa-bbbs = "Hello, Python!"# 查找子字符串的位置print(s.find("Python")) # 7(从索引7开始)print(s.find("Java")) # -1(找不到返回-1)# 从指定位置开始找print(s.find("l", 3)) # 从索引3开始找"l"7-13s = "Hello, Python!"print(s.upper()) # 全部大写print(s.lower()) # 全部小写print(s.title()) # 每个单词首字母大写print(s.swapcase()) # 大小写互换HELLO, PYTHON!hello, python!Hello, Python!hELLO, pYTHON!filename = "photo_2024.jpg"# 是否以某个字符串开头print(filename.startswith("photo"))print(filename.startswith("video"))# 是否以某个字符串结尾print(filename.endswith(".jpg"))print(filename.endswith(".png"))TrueFalseTrueFalse💡 这两个方法在文件处理时特别常用!比如判断一个文件是不是图片:if filename.endswith((".jpg", ".png", ".gif")): print("是图片文件")
split(sep) | "a,b,c".split(",") | |
join(list) | ",".join(['a','b']) | |
strip() | " hi ".strip() | |
replace(old, new) | "abc".replace("b","X") | |
find(sub) | "hello".find("ll") | |
upper() | "hi".upper() | |
lower() | "HI".lower() | |
startswith(s) | "hello".startswith("he") | |
endswith(s) | "hello".endswith("lo") | |
count(sub) | "banana".count("a") |
Python 字符串方法就像瑞士军刀上的各种工具,各司其职
字符串一旦创建,就不能修改其中的某个字符。
这就像刻在石头上的字——你不能直接改某个笔画,只能重新刻一块新石头。
s = "Hello"# ❌ 不能直接修改某个字符# s[0] = "h" # TypeError: 'str' object does not support item assignment# ✅ 正确做法:创建一个新字符串s = "h" + s[1:]print(s) # hello# 或者用 replaces = "Hello"s = s.replace("H", "h")print(s)hellohello💡 为什么字符串要设计成不可变?1. 安全:不用担心别人偷偷改了你的字符串2. 高效:Python 可以缓存和复用相同内容的字符串3. 可哈希:可以当字典的 key(后面会学到)就像银行存折上的数字——你可以开一张新的存折,但不能在原存折上涂改。
# 不可变意味着每次"修改"都创建了新对象s1 = "Hello"s2 = s1s1 = s1 + " World"print(s1) # Hello World(新字符串)print(s2) # Hello(原来的没变!)Hello WorldHellofirst = "张"last = "三"name = first + lastprint(name)# 拼接多个greeting = "你好," + name + "!欢迎来到Python世界!"print(greeting)张三你好,张三!欢迎来到Python世界!words = ["我", "爱", "学", "Python"]# 用 + 号(不推荐)result = words[0] + words[1] + words[2] + words[3]print(result)# 用 join(推荐!)result = "".join(words)print(result)# 还能加分隔符result = ",".join(words)print(result)我爱学Python我爱学Python我,爱,学,Python💡 为什么 join 更好?用 + 拼接时,Python 每次都会创建一个新的字符串对象。拼接1000次,就创建1000个临时对象,很浪费内存。join() 一次性算好总长度,只创建一个新字符串,效率高很多!就像:+ = 每加一块砖就盖一次房子,盖了拆、拆了盖 ❌join() = 先算好需要多少砖,一次性盖好 ✅
# 性能对比(拼接大量字符串时)import time# 用 + 号start = time.time()s = ""for i in range(10000): s += str(i)print(f"+ 号拼接耗时:{time.time() - start:.4f}秒")# 用 joinstart = time.time()s = "".join(str(i) for i in range(10000))print(f"join 拼接耗时:{time.time() - start:.4f}秒")+ 号拼接耗时:0.0031秒join 拼接耗时:0.0018秒🏆 结论:少量拼接用 + 没问题(更直观),大量拼接用 join(更高效)。
字符串拼接就像把一段段文字组合成完整的文章
给定字符串 s = "Hello, Python!",用索引打印出:
s = "Hello, Python!"print(s[0]) # Hprint(s[-1]) # !print(s[5:7]) # , 用切片把字符串 "abcdefg" 反转成 "gfedcba"。
s = "abcdefg"print(s[::-1]) # gfedcba用 f-string 输出:姓名、年龄、身高(保留1位小数)、城市。
name = "小明"age = 18height = 175.567city = "北京"print(f"姓名:{name}")print(f"年龄:{age}岁")print(f"身高:{height:.1f}cm")print(f"城市:{city}")姓名:小明年龄:18岁身高:175.6cm城市:北京给定一句英文,完成以下操作:
s = "I love Python programming"print(s.upper())print(len(s.split()))print(s.replace(" ", "_"))I LOVE PYTHON PROGRAMMING4I_love_Python_programming检查一个字符串是否像合法的邮箱地址(包含 @ 且以 .com 或 .cn 结尾)。
email = "test@example.com"if "@" in email and (email.endswith(".com") or email.endswith(".cn")): print(f"{email} 是合法的邮箱地址")else: print(f"{email} 不是合法的邮箱地址")test@example.com 是合法的邮箱地址s[i] 取第 i 个字符,正向从0开始,反向从-1开始 | |
s[start:end:step] 截取子串,左闭右开 | |
f"内容{变量}" | |
+,大量用 join |
⬜ 知道 Python 索引从 0 开始
⬜ 能用 s[-1] 取最后一个字符
⬜ 理解切片的"左闭右开"规则
⬜ 能用 s[::-1] 反转字符串
⬜ 会用 f-string 格式化输出
⬜ 掌握 split、join、strip、replace、find 等常用方法
⬜ 知道字符串是不可变的
⬜ 了解 + 和 join 拼接的区别
明天我们将学习 列表(list)——Python 中最常用的数据结构,就像一个可以随意增删改查的"购物清单"。
字符串是"固定的手链",列表是"可拆卸的乐高积木" 🧱
📅 Day 3 完成!你已经掌握了字符串的基本操作,明天继续加油!🚀
请在微信客户端打开