欢迎光临
我们一直在努力

04 字符串详解:办公场景的第一刚需(拼接 · 切片 · f-string · 清洗三件套)

上一篇:03 变量与数据类型:给数据贴标签(数字 · 字符串 · 布尔 · type())


上篇练习参考答案

练习 1:三行自我介绍:定义 name、age、hourly_pay 三个变量(类型分别是 str、int、int),用一个 print 打印成一句话; 在这里插入图片描述

练习 2(预测再验证):先不运行,写下你认为 type(“3.14”)、type(3.14)、type(3 == 3) 的输出;然后进交互模式验证,错了的写在评论区; type("3.14") → <class 'str'>(有引号是字符串);type(3.14) → <class 'float'>;type(3 == 3) → <class 'bool'>。前两个最容易错。 在这里插入图片描述

练习 3(total 的类型):小票改造:把加班费小算盘改成你自己的真实时薪和加班时长,运行后把小票贴在评论区;顺手回答:你的 total 是 int 还是 float?为什么? total 是 float,因为 weekday_rate 与 weekend_rate 都是浮点数,整数乘浮点数结果就是浮点数。 在这里插入图片描述

练习 4(“1.5” 疫苗)——答案比预想的更精彩:把 weekday_rate 改成 1.5 改成 “1.5”(加引号),运行看报什么错,按三段式写出错误类型、位置、修法——这道题就是为模块二"从 Excel 读出来的数字不能直接算"提前打的疫苗

把 weekday_rate = "1.5" 加上引号后,50 * 3 * "1.5" 并不报错,而是静悄悄生成一个把 "1.5" 重复 150 遍的巨长字符串(字符串乘整数 = 重复,第 2 篇的 "=" * 30 就是这个原理);直到算 total = weekday_pay + weekend_pay(字符串 + 浮点数)才爆炸: 在这里插入图片描述

TypeError: can only concatenate str (not "float") to str

教训有两条:① 类型错误不一定在出错的那一行立刻报,可能先潜伏、后爆炸,甚至一路不报只是结果全错——这种"静默出错"比报错可怕得多;② type() 随时体检,是唯一可靠的防线。这也正是模块二"从 Excel 读出的数字先 type 检查再运算"的原因。


一、场景引入:真实世界的数据,从来不干净

在这里插入图片描述

第 3 篇我们亲手定义了干干净净的变量。但真实工作里,数据长这样:

  • 从微信群里复制来的名单:" 张三 ,李四 ;王五 ";
  • 从表单导出的邮箱:" xingyu@MAIL.com ";
  • 财务系统吐出来的金额:"12580.456"(精确到厘,但你只想看到两位小数)。

办公自动化的一半工作量,就是把脏数据洗成规范数据。 而洗数据的工具箱,几乎全是字符串方法——这就是本篇标题里"第一刚需"的意思。上篇埋的 f-string 伏笔,本篇也正式揭晓。

二、本篇目标

  • 正式掌握 f-string:插值、金额格式化(两位小数 + 千分位)、对齐;
  • 用索引和切片截取文字的任意一段(实战:手机号脱敏);
  • 掌握清洗三件套 strip / split / join 加 replace、upper/lower、in。
  • 三、知识点讲解

    3.1 拼接与 f-string:文字组装流水线

    方式一:+ 拼接——两边必须都是字符串(03 篇报错 1 的坑还历历在目):

    first = "星"
    last = "宇Py"
    print(first + last) # 星宇Py

    在这里插入图片描述

    方式二:f-string(正式揭晓)——引号前加 f,{} 里的内容会被"求值后填进去"(注:python3 才支持f-string,python2 不支持f-string):

    以下为 python2 运行 f-string 会报语法错误+中文乱码,所以我们课程都是在最新的 python3 里运行 如果有用 python2 的同学需要先按本专栏 01 环境搭建课 安装一个 python3 环境后再进行练习 在这里插入图片描述

    name = "星宇Py"
    pay = 625.0
    print(f"{name} 本月加班费 {pay} 元") # 星宇Py 本月加班费 625.0 元
    print(f"明年目标:{pay * 2} 元") # {} 里可以放算式(pay乘2):1250.0 元

    python3 环境运行 在这里插入图片描述

    f-string 的三个杀手锏,+ 拼接一个都做不到:

    杀手锏一:数字直接放进来,不用 str() 变身——从此告别 TypeError 拼接报错,通过 f"{变量名}" 语法放入的变量无论之前是什么类型都会自动转为字符串。

    杀手锏二:金额格式化。冒号后面接格式说明符,如::,.2f = 千分位 + 固定两位小数:

    amount = 12580.456
    print(f"{amount}") # 12580.456
    print(f"{amount:.2f}") # 12580.46(两位小数)
    print(f"{amount:,.2f}") # 12,580.46(千分位 + 两位小数)

    在这里插入图片描述

    给老板看的金额,一律 :,.2f。一行代码,专业感拉满。

    杀手锏三:对齐排版。:<10 左对齐占 10 格、:^10 居中、:>10 右对齐(数字常用右对齐,个位对齐):

    print(f"|{'项目':<6}|{'金额':>8}|")

    在这里插入图片描述

    以后打印小票、对账单,全靠它。本专栏后续所有代码的输出排版,默认用 f-string。

    一句话结论:从今天起,python3里"往文字里塞值"只写 f-string。 + 拼接只用于两个字符串字面量直接相连的简单场景。

    3.2 索引与切片:像切香肠一样取文字

    字符串里的每个字符都有编号,从左往右 0 开始数 ,从右往左 -1 开始数:

    word = "Python"
    # 文字: P y t h o n
    # 从左往右数: 0 1 2 3 4 5
    # 从右往左数: -6 -5 -4 -3 -2 -1
    print(word[0]) # P(第 0 个)
    print(word[5]) # n(第 6 个字符,编号是 5)
    print(word[1]) # n(负数从右往左数,-1 是最后一个)
    print(word[2]) # o(负数从右往左数,-2 是倒数第二个)
    print(word[6]) # P(负数从右往左数,-6 是倒数第六个)

    在这里插入图片描述

    切片 [起:止]:含头不含尾(本篇最重要的四个字):

    phone = "12345678910"
    # 内容: 1 2 3 4 5 6 7 8 9 1 0
    # 从左往右数: 0 1 2 3 4 5 6 7 8 9 10
    # 从右往左数: -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1
    print(phone[0:3]) # 123(编号 0、1、2,不含编号 3)
    print(phone[3:7]) # 4567(编号 3、4、5、6,不含编号 7)
    print(phone[4:]) # 8910(省略"止"= 从倒数第4个一直取到末尾)
    print(phone[:3]) # 123(省略"起"= 从头开始一直到编号3,不包括编号3本身)

    在这里插入图片描述

    三个组合拳立刻打一个实战——手机号脱敏(把中间四位打码,财务和运营发通知时的常规操作):

    phone = "12345678910"
    masked = phone[:3] + "****" + phone[4:]
    print(masked) # 123****8910

    在这里插入图片描述

    一行切片 + 一行拼接,过去手工打码的活儿变成了一行代码。len() 数一下字符串有几个字符(中文一个字算一个字符):len("你好Py") 是 4。

    3.3 清洗三件套与常备工具

    strip()——只剪两头的空格:

    注:下面 + ‘|’ 是因为输出的结果里右侧空格是否存在肉眼看不出来,所以加一个标志让肉眼可以看到右侧是否有空格 在这里插入图片描述

    raw = " xing yuPY "
    print(raw.strip() + '|') # xing yuPY|(两头空格全去,注意:中间的空格不管!strip 只管两头)
    print(raw.lstrip() + '|') # xing yuPY |(lstrip 只去左边空格)
    print(raw.rstrip() + '|') # xing yuPY|(rstrip 只去右边空格)
    print(raw.lstrip().rstrip() + '|') # xing yuPY|(先 lstrip 只去左边空格,再 rstrip 只去右边空格 = strip 两头空格全去 )

    在这里插入图片描述

    split()——按分隔符切成几段。结果用下标取出(下标语法和 3.2 节同款,这套 [0] [1] 以后对列表也通用):

    record = "星宇Py ; 12345678910 ;12580.456"
    parts = record.split(";")
    print(parts[0].strip()) # 星宇Py (注意分隔符右侧的空格会保留)
    print(parts[1].strip()) # 12345678910(所以切完通常再 strip 一次)
    print(parts[2].strip()) # 12580.456(.strip() 有空格去空格,如果没有空格也不会报错)

    在这里插入图片描述

    join()——把几段粘回一个字符串,和 split 是一对反操作:

    names = ["张三", "李四", "王五"]
    print("、".join(names)) # 张三、李四、王五

    在这里插入图片描述

    常备四件:replace(旧, 新) 替换、upper()/lower() 大小写转换、title() 每个单词首字母大写、in 判断包含:

    print("123-456-78910".replace("-", "")) # 12345678910(洗掉横线)
    print("xing yu".upper()) # XING YU(统一大写)
    print("xingyu@MAIL.com".lower()) # xingyu@mail.com(统一小写,比对邮箱必备)
    print("xing yuPY".title()) # Xing Yupy(姓名规范显示)
    print("Py" in "Python") # True("在不在里面")
    print("星" in "星宇Py") # True

    在这里插入图片描述

    工具箱清点完毕:插值找 f-string,截取找切片,清洗找 strip/split/join,加工找 replace/大小写,判断找 in。

    四、完整实战:客户登记信息清洗器

    场景:报名表单吐出来一条脏数据——前后空格、姓名大小写混乱、金额精度超标。我们要把它洗成规范记录。新建 客户信息清洗器.py(点击py名下载):

    # ===== 客户登记信息清洗器 =====
    # 模拟从表单收到的一条原始脏数据:前后空格、分隔符后空格不齐、大小写乱、金额精度超标
    raw = " xing yuPY ; 12345678910 ; 12580.456 "

    print("=" * 44)
    print(" 客户登记信息清洗器")
    print("=" * 44)
    print(f"原始数据:{raw}")
    print("-" * 44)

    # 第一步:按分号切成三段(切完每段单独 strip)
    parts = raw.split(";")
    name_raw = parts[0]
    phone_raw = parts[1]
    amount_raw = parts[2]

    # 第二步:逐项清洗
    name = name_raw.strip().title() # 去两头空格 + 单词首字母大写
    phone = phone_raw.strip() # 去两头空格
    amount = float(amount_raw.strip()) # 字符串变身浮点数,才能参与算术

    # 第三步:加工输出(切片脱敏 + 金额格式化)
    phone_masked = phone[:3] + "****" + phone[4:]
    print(f"姓名:{name}")
    print(f"手机:{phone_masked}(完整 {len(phone)} 位)")
    print(f"金额:{amount:,.2f} 元(原始精度 {amount})")

    # 第四步:join 粘回一条规范记录
    record = "、".join([name, phone_masked, f"{amount:,.2f}元"])
    print("-" * 44)
    print(f"规范记录:{record}")
    print("=" * 44)

    # 附:大小写无关的包含判断(以后做筛选常用)
    print(f"姓名里含 'xing' 吗:{'xing' in name.lower()}")

    流程对照工具箱:split 切开 → strip 洗净 → title/切片/f-string 加工 → join 封装。这就是一条完整的数据清洗流水线,模块二处理 Excel 时把"从表单读"换成"从表格读",流水线原封不动。

    五、运行效果

    在这里插入图片描述

    ——————————————–
    姓名:Xing Yupy
    手机:123****8910(完整 11 位)
    金额:12,580.46 元(原始精度 12580.456)
    ——————————————–
    规范记录:Xing Yupy、123****8910、12,580.46元
    ============================================
    姓名里含 'xing' 吗:True

    对照看两个细节:金额从 12580.456 变成 12,580.46;手机号中间四位永远打码——原始数据不动,展示时脱敏,这是处理个人信息的安全习惯。

    六、常见报错与排查

    报错 1:IndexError: string index out of range(下标越界)

    phone = "12345678910"
    print(phone[11])

    在这里插入图片描述

    原因:11 位手机号的编号是 0~10,取 phone[11] 越界了。注意长度 len(phone) 是 11,但最大编号是 len(phone) – 1。 解决:拿不准先 print(len(x)) 数一遍;或改用切片——切片越界不报错,phone[5:99] 会安静地取到末尾为止。

    报错 2:AttributeError: 'str' object has no attribute 'stripp'(方法名拼错)

    " abc ".stripp()

    在这里插入图片描述

    原因:方法名拼写错误(stripp、replase、spilt 都是高频手滑)。 解决:看报错里的 Did you mean 提示;字符串方法都是对原字符串调用、返回新结果,所以必须写成 x = x.strip()——只写 x.strip() 不赋值,等于洗完澡又跳回泥坑。

    报错 3:ValueError: could not convert string to float(变身失败)

    float(" 12580.456元 ")

    在这里插入图片描述

    原因:float() 只认"纯数字字符串",末尾多个"元"字就变不了身。 解决:先洗再变——float("12580.456元".replace("元", "").strip())。顺序很重要:清洗在前,转换在后。

    坑 1(不报错但结果错):f-string 忘写 f

    print("{name} 你好") 不报错,但会原样打印 {name} 你好。看到输出里带花括号,第一反应就是检查引号前的 f。 在这里插入图片描述

    坑 2(不报错但结果错):strip 去不掉中间空格

    "星 宇 Py".strip() 只去两头。想去掉所有空格用 "星 宇 Py".replace(" ", "")。 在这里插入图片描述

    七、练习作业(5 分钟)

  • 脱敏变式:把手机号脱敏改成"显示前 3 位和后 2 位、中间打 6 个星"(如 138******78),只用切片和拼接实现;
  • 预测再验证:先写出 len("Python")、"Python"[0:2]、"PYTHON".lower() == "python" 三项的结果,再进交互模式验证,错的写在评论区;
  • 名单整理(本篇招牌题):有名单 " 张三 , 李四 ;王五、赵六 ",用 replace 统一分隔符后 split + join,输出 张三、李四、王五、赵六,并用 len() 数出一共几人;
  • 选做(模块二预热):把 "1,258,045" 变回数字 1258045.0(提示:先 replace 去千分位逗号,再 float 变身)——Excel 导出的数字常带千分位逗号,这就是洗它的标准姿势。

  • 下一篇预告:《05 列表:批量数据的容器》——一个变量装下一整份名单。增删改查、append/insert、遍历入门,你的代码将从"处理一条数据"升级为"处理一沓数据"。

    赞(0)
    未经允许不得转载:171主机测评 » 04 字符串详解:办公场景的第一刚需(拼接 · 切片 · f-string · 清洗三件套)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址