Phương thức chuỗi
Bạn sẽ học được
- Cắt khoảng trắng, tách và ghép chuỗi — ba thao tác làm sạch dữ liệu phổ biến nhất.
- Tìm, thay thế, đổi hoa thường.
- Kiểm tra tiền tố, hậu tố, loại ký tự.
- Cắt chuỗi bằng chỉ số và slice.
- Vì sao chuỗi bất biến và mọi phương thức đều trả chuỗi mới.
Khái niệm cốt lõi
Chuỗi trong Python có hơn 40 phương thức. Không cần nhớ hết; nhớ nhóm và tra dir(str) khi cần. Bài này đi qua nhóm dùng hằng ngày trong làm sạch dữ liệu.
raw = " Data,SQL,Python "
print(raw.strip().split(","))['Data', 'SQL', 'Python']Một dòng, hai bước: strip() bỏ khoảng trắng hai đầu, split(",") tách theo dấu phẩy. Đây chính là cách đọc một dòng CSV đơn giản trước khi cần đến thư viện csv.
Mọi phương thức chuỗi đều trả về chuỗi mới, không sửa tại chỗ:
name = "an"
name.upper()
print(name)anKết quả upper() bị bỏ vì không gán lại. Viết name = name.upper() hoặc name.upper() ngay trong biểu thức. Đây là lỗi im lặng — chương trình chạy, không báo gì, nhưng dữ liệu không đổi.
Nhóm làm sạch
| Phương thức | Việc nó làm |
|---|---|
strip() | Bỏ khoảng trắng (hoặc ký tự chỉ định) hai đầu |
lstrip() / rstrip() | Chỉ bỏ bên trái / bên phải |
lower() / upper() | Đổi hoa thường |
title() / capitalize() | Viết hoa đầu từ / đầu chuỗi |
casefold() | Chuẩn hoá mạnh hơn lower(), dùng khi so sánh |
print(" an@example.com ".strip().upper())
print("__data__".strip("_"))
print("Hà Nội".lower())AN@EXAMPLE.COM
data
hà nộistrip("_") bỏ mọi ký tự _ ở hai đầu, không chỉ một cặp. strip() không có tham số bỏ mọi loại khoảng trắng: dấu cách, tab, xuống dòng.
Trong dữ liệu thật, chuỗi có thể chứa ký tự không nhìn thấy như non-breaking space (\xa0) từ Excel hoặc HTML. strip() không bỏ ký tự này. Cần xử lý riêng:
text = "An\xa0"
print(repr(text.strip()))
print(repr(text.replace("\xa0", " ").strip()))Tách và ghép
line = "An,28,Hà Nội"
parts = line.split(",")
print(parts)
print(len(parts))
print(line.split(",", maxsplit=1))['An', '28', 'Hà Nội']
3
['An', '28,Hà Nội']maxsplit giới hạn số lần tách — hữu ích khi phần còn lại có thể chứa dấu phân cách (ví dụ địa chỉ có dấu phẩy).
split() không tham số tách theo mọi khoảng trắng và bỏ khoảng trắng thừa, khác split(" "):
print("An Nguyễn".split())
print("An Nguyễn".split(" "))['An', 'Nguyễn']
['An', '', '', 'Nguyễn']Đây là lý do nên dùng split() trần khi tách từ.
Ghép ngược lại bằng join:
print(" | ".join(["Data", "SQL", "Python"]))
print(",".join(["An", "Bình"]))Data | SQL | Python
An,Bìnhjoin được gọi trên dấu phân cách, nhận iterable chuỗi. Nếu danh sách chứa số, phải ép kiểu trước: ",".join(map(str, nums)).
Tách dòng: "a\nb".splitlines() trả ['a', 'b'] và xử lý đúng cả \r\n trên Windows.
Tìm và thay thế
s = "Data Analysis with Python"
print(s.find("Python"))
print(s.count("a"))
print(s.replace("Python", "SQL"))
print(s.startswith("Data"), s.endswith("Python"))19
4
Data Analysis with SQL
True Truefind()trả chỉ số đầu tiên hoặc-1nếu không thấy.index()giống nhưng némValueError— dùng khi chắc chắn phải có.count()đếm số lần xuất hiện, phân biệt hoa thường.replace()thay tất cả; tham số thứ ba giới hạn số lần.startswith()/endswith()nhận tuple để kiểm tra nhiều khả năng:s.endswith((".csv", ".xlsx")).
Kiểm tra thành viên bằng in:
print("SQL" in s, "sql" in s)True Falsein phân biệt hoa thường. Muốn không phân biệt, chuẩn hoá cả hai phía: "sql" in s.lower().
Cắt chuỗi
code = "VN-2025-001"
print(code[:2])
print(code[3:7])
print(code[-3:])
print(code[::-1])VN
2025
001
100-5202-NVCú pháp [start:stop:step], stop không bao gồm. Chỉ số âm đếm từ cuối. [::-1] đảo chuỗi — cách viết gọn nhưng với dữ liệu lớn nên dùng cách rõ ràng hơn.
Cắt chuỗi không bao giờ ném lỗi khi vượt biên:
print(code[100:])(empty)Khác với truy cập một chỉ số: code[100] ném IndexError.
Kiểm tra loại ký tự
| Phương thức | True khi |
|---|---|
isdigit() | Toàn chữ số (kể cả số Unicode) |
isdecimal() | Chỉ chữ số thập phân |
isalpha() | Toàn chữ cái |
isalnum() | Chữ và/hoặc số, không khoảng trắng |
isspace() | Toàn khoảng trắng |
isdigit() trả True cho "²" (chữ số trên), nhưng int("²") lỗi. Khi cần kiểm tra để ép kiểu, isdecimal() an toàn hơn — hoặc cứ dùng try/except và để Python quyết định.
Thực hành
- Làm sạch
" Data,SQL,Python "thành danh sách ba phần tử. - Ghép danh sách
["An", "Bình", "Chi"]bằng" | ". - Đếm chữ
atrong một câu bất kỳ, không phân biệt hoa thường. - Kiểm tra một tên file kết thúc bằng
.csvhoặc.xlsx. - Cắt mã
"VN-2025-001"lấy năm và số thứ tự. - Thử
name.upper()mà không gán lại và giải thích vì saonamekhông đổi.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách sửa |
|---|---|---|
Chuỗi không đổi sau strip() | Không gán kết quả | x = x.strip() |
split(" ") tạo phần tử rỗng | Nhiều khoảng trắng liền nhau | Dùng split() trần |
join báo TypeError | Danh sách chứa số | map(str, ...) |
find() trả -1 | Không tìm thấy | Kiểm tra hoặc dùng index() |
in không khớp dù thấy bằng mắt | Khác hoa thường hoặc có ký tự ẩn | Chuẩn hoá lower()/strip() |
IndexError khi cắt | Truy cập bằng chỉ số, không phải slice | Dùng [start:stop] |
| So sánh chuỗi Unicode lạ | Dạng tổ hợp khác nhau | unicodedata.normalize |
Lỗi cuối ít gặp nhưng khó chẩn đoán: "é" có thể được lưu dưới hai dạng Unicode (một ký tự hoặc e + dấu sắc tổ hợp). Hai chuỗi trông giống hệt nhưng == trả False. Chuẩn hoá NFC trước khi so sánh nếu dữ liệu đến từ nhiều nguồn.
Tóm tắt
strip,split,joinlà bộ ba làm sạch dữ liệu.split()trần tách theo khoảng trắng và bỏ phần rỗng.- Chuỗi bất biến: mọi phương thức trả chuỗi mới, phải gán lại.
findtrả-1,indexném lỗi;countphân biệt hoa thường.- Slice không ném
IndexError; truy cập chỉ số thì có.
Dùng ← → để chuyển bài