Python 中如何将字符串转换为小写?
Python 里把字符串转小写,别只知道 lower()
导入脚本跑完,邮箱去重还是重复。
一看数据,气得人想关电脑:
[email protected]
[email protected]
[email protected]
肉眼看是一个邮箱,程序看是三个字符串。 这种问题我一般不先怀疑数据库,也不先怀疑去重逻辑,先看清洗有没有做大小写统一。很多脏数据就是这么混进去的。
Python 里最常用的写法就一行:
email = "[email protected]"
email = email.lower()print(email)
# [email protected]
lower() 会返回一个新的字符串,不会改原来的字符串。
这一点得记一下。字符串在 Python 里是不可变对象,你写:
name = "OrderStatus"name.lower()
print(name)
# OrderStatus
这段代码看着调用了 lower(),其实啥也没接住。线上清洗脚本里我见过这种写法,跑完一堆数据,结果字段还是原样。正确写法是重新赋值:
name = "OrderStatus"
name = name.lower()print(name)
# orderstatus
如果只是普通英文、接口字段、日志级别、状态码这些,用 lower() 就够了。
比如接口传来的状态值不稳定:
raw_status = " PAID "status = raw_status.strip().lower()
if status == "paid":
print("订单已支付")
这里我一般会顺手加上 strip()。因为真实数据里,大小写不是唯一的问题,前后空格也很常见。尤其是 Excel 导入、CSV 导入、人工后台录入,别太相信输入源。
再比如清洗一批用户名:
users = ["Admin", "testUser", "OPS", "guest "]clean_users = []
for user in users:
clean_users.append(user.strip().lower())
print(clean_users)
# ['admin', 'testuser', 'ops', 'guest']
别为了这一点写得花里胡哨。数据量不大,循环就挺清楚。后面真慢了,再说优化。
当然,也可以写成列表推导:
users = ["Admin", "testUser", "OPS", "guest "]clean_users = [user.strip().lower() for user in users]
print(clean_users)
这个写法适合一眼能看懂的场景。要是里面还夹着判空、字段拆分、异常兜底,我宁愿拆成普通循环,后面排问题省事。
有个坑也得提一下。lower() 不是类型转换器,它只处理字符串。你给它塞个 None 或数字,它会直接报错:
value = Noneprint(value.lower())
报错大概是这样:
AttributeError: 'NoneType' object has no attribute 'lower'
导入脚本里这种最常见。某一行字段为空,脚本跑到一半炸了。我的习惯是先写一个小函数,把脏值挡在外面:
defnormalize_text(value):
if value isNone:
return""return str(value).strip().lower()
row = {
"email": " [email protected] ",
"level": "ERROR",
"remark": None,
}
email = normalize_text(row.get("email"))
level = normalize_text(row.get("level"))
remark = normalize_text(row.get("remark"))
print(email, level, remark)
# [email protected] error
这段不高级,但抗揍。 我宁可这里啰嗦一点,也不愿意让清洗任务凌晨跑到第 8 万行突然挂掉。
还有一个方法叫 casefold(),很多人平时用不到,但知道它有必要。它比 lower() 更适合做“不区分大小写”的比较,尤其涉及一些非英文字符时。
left = "Straße"
right = "STRASSE"print(left.lower() == right.lower())
# False
print(left.casefold() == right.casefold())
# True
所以我的取舍一般是这样:
普通业务字段、英文状态、邮箱、用户名,用 lower()。
要做更严格的大小写无关比较,特别是多语言文本,用 casefold()。
比如封装成一个判断函数:
defsame_text(left, right):
if left isNoneor right isNone:
returnFalsereturn str(left).strip().casefold() == str(right).strip().casefold()
print(same_text("Admin", " admin "))
# True
print(same_text("Straße", "STRASSE"))
# True
还有个细节,别把“转小写”和“改显示文案”混在一起。
比如商品标题:
title = "iPhone 15 Pro Max"
你要是直接:
title = title.lower()
结果就变成:
iphone 15 pro max
这在搜索索引里可能没问题,但拿去页面展示就很怪。 所以我一般会分两个字段,一个用于展示,一个用于检索:
product = {
"display_name": "iPhone 15 Pro Max",
}product["search_name"] = product["display_name"].casefold()
print(product)
排查搜索搜不到、去重不准、状态判断失效这类问题时,我会先看这种字段有没有统一清洗,而不是上来就翻一堆业务代码。
Python 转小写本身没什么复杂的。
真正容易出问题的是这几个地方:
lower() 返回新字符串,别忘了接收。
清洗前先处理空值。
真实数据通常还有空格,strip() 经常要一起用。
普通英文用 lower(),严格比较用 casefold()。
展示字段和检索字段别混着改。
这东西小,但线上脏数据最喜欢从这种小口子钻进来。