Bài 3.3. Phương thức chuỗi Python: count và các phương thức khác

Trong thế giới lập trình Python, chuỗi (string) là một kiểu dữ liệu cực kỳ quan trọng và được sử dụng thường xuyên. Việc thao tác, xử lý và trích xuất thông tin từ chuỗi là một kỹ năng không thể thiếu. May mắn thay, Python cung cấp một bộ sưu tập phong phú các phương thức chuỗi (string methods) tích hợp sẵn, giúp chúng ta thực hiện những công việc này một cách dễ dàng và hiệu quả.

Bài viết này sẽ tập trung vào phương thức count() – một công cụ hữu ích để đếm số lần xuất hiện của một chuỗi con – và đồng thời khám phá thêm nhiều phương thức quan trọng khác, biến bạn thành một bậc thầy xử lý chuỗi trong Python!

Phương thức count() - Đếm số lần xuất hiện

Hãy bắt đầu với "ngôi sao" của bài viết: phương thức count(). Đúng như tên gọi, count() giúp bạn đếm xem một chuỗi con (substring) cụ thể xuất hiện bao nhiêu lần bên trong một chuỗi lớn hơn.

Cú pháp:

string.count(substring, start=0, end=len(string))

Giải thích tham số:

  • substring: Chuỗi con mà bạn muốn tìm kiếm và đếm. Đây là tham số bắt buộc.
  • start (tùy chọn): Vị trí chỉ mục (index) bắt đầu tìm kiếm trong chuỗi gốc. Mặc định là 0 (bắt đầu từ đầu chuỗi).
  • end (tùy chọn): Vị trí chỉ mục kết thúc tìm kiếm trong chuỗi gốc (không bao gồm vị trí này). Mặc định là len(string) (tìm kiếm đến hết chuỗi).

Lưu ý quan trọng: Phương thức count() thực hiện việc đếm không chồng chéo (non-overlapping).

Ví dụ minh họa:

  1. Đếm cơ bản:

    my_string = "Chào mừng bạn đến với thế giới lập trình Python. Python thật tuyệt!"
    
    # Đếm số lần xuất hiện của 'Python'
    count_python = my_string.count("Python")
    print(f"Số lần 'Python' xuất hiện: {count_python}") # Output: Số lần 'Python' xuất hiện: 2
    
    # Đếm số lần xuất hiện của ký tự 'n'
    count_n = my_string.count("n")
    print(f"Số lần ký tự 'n' xuất hiện: {count_n}") # Output: Số lần ký tự 'n' xuất hiện: 7
    

    Giải thích: Trong ví dụ này, my_string.count("Python") tìm và đếm tất cả các lần chuỗi "Python" xuất hiện trong my_string, kết quả là 2. Tương tự, my_string.count("n") đếm tất cả các ký tự 'n'.

  2. Phân biệt chữ hoa/thường (Case-sensitive):

    my_string = "Python is pythonic, python is fun."
    
    count_lower = my_string.count("python")
    print(f"Số lần 'python' (thường) xuất hiện: {count_lower}") # Output: Số lần 'python' (thường) xuất hiện: 2
    
    count_upper = my_string.count("Python")
    print(f"Số lần 'Python' (hoa) xuất hiện: {count_upper}") # Output: Số lần 'Python' (hoa) xuất hiện: 1
    

    Giải thích: count() có phân biệt chữ hoa và chữ thường. "python" và "Python" được coi là hai chuỗi con khác nhau.

  3. Sử dụng startend:

    my_string = "banana banana banana"
    
    # Đếm 'banana' từ vị trí 7 trở đi
    count_from_7 = my_string.count("banana", 7) 
    print(f"Đếm 'banana' từ vị trí 7: {count_from_7}") # Output: Đếm 'banana' từ vị trí 7: 2
    
    # Đếm 'na' trong khoảng từ vị trí 2 đến 10 (my_string[2:10] là 'nana ban')
    count_na_slice = my_string.count("na", 2, 10)
    print(f"Đếm 'na' từ vị trí 2 đến 10: {count_na_slice}") # Output: Đếm 'na' từ vị trí 2 đến 10: 2
    

    Giải thích:

    • my_string.count("banana", 7) bắt đầu tìm kiếm "banana" từ chỉ mục 7 ("banana banana"). Nó tìm thấy 2 lần xuất hiện.
    • my_string.count("na", 2, 10) tìm kiếm "na" trong lát cắt my_string[2:10], tức là chuỗi "nana ban". Nó tìm thấy "na" 2 lần trong lát cắt này.
  4. Đếm không chồng chéo:

    my_string = "aaaaaa"
    
    # Đếm 'aa'
    count_aa = my_string.count("aa")
    print(f"Số lần 'aa' xuất hiện (không chồng chéo): {count_aa}") # Output: Số lần 'aa' xuất hiện (không chồng chéo): 3
    
    # Đếm 'aaa'
    count_aaa = my_string.count("aaa")
    print(f"Số lần 'aaa' xuất hiện (không chồng chéo): {count_aaa}") # Output: Số lần 'aaa' xuất hiện (không chồng chéo): 2
    

    Giải thích:

    • Khi đếm "aa" trong "aaaaaa", Python tìm thấy "aa" đầu tiên ở vị trí 0. Lần tìm kiếm tiếp theo sẽ bắt đầu sau lần tìm thấy đó (tức là từ vị trí 2). Nó tìm thấy "aa" ở vị trí 2, rồi tiếp tục tìm từ vị trí 4 và tìm thấy "aa" cuối cùng. Do đó, kết quả là 3.
    • Tương tự, khi đếm "aaa", nó tìm thấy "aaa" ở vị trí 0. Lần tìm tiếp theo bắt đầu từ vị trí 3 và tìm thấy "aaa" thứ hai. Kết quả là 2.

Các phương thức chuỗi hữu ích khác

Ngoài count(), Python còn trang bị hàng loạt "vũ khí" khác để bạn thao tác với chuỗi:

1. Tìm kiếm vị trí: find()index()

Cả hai phương thức này đều dùng để tìm vị trí xuất hiện đầu tiên của một chuỗi con.

  • find(substring, start, end): Trả về chỉ mục (index) thấp nhất nơi substring được tìm thấy. Nếu không tìm thấy, nó trả về -1.
  • index(substring, start, end): Hoạt động tương tự find(), nhưng nếu không tìm thấy substring, nó sẽ gây ra lỗi ValueError thay vì trả về -1.
my_string = "Học Python để làm chủ dữ liệu."

# Sử dụng find()
pos_python_find = my_string.find("Python")
print(f"Vị trí 'Python' (dùng find): {pos_python_find}") # Output: Vị trí 'Python' (dùng find): 4

pos_java_find = my_string.find("Java")
print(f"Vị trí 'Java' (dùng find): {pos_java_find}") # Output: Vị trí 'Java' (dùng find): -1

# Sử dụng index()
pos_python_index = my_string.index("Python")
print(f"Vị trí 'Python' (dùng index): {pos_python_index}") # Output: Vị trí 'Python' (dùng index): 4

try:
    pos_java_index = my_string.index("Java")
    print(f"Vị trí 'Java' (dùng index): {pos_java_index}") 
except ValueError as e:
    print(f"Lỗi khi dùng index() tìm 'Java': {e}") # Output: Lỗi khi dùng index() tìm 'Java': substring not found

Giải thích: find() trả về -1 khi không tìm thấy "Java", trong khi index() gây lỗi ValueError. Nên sử dụng find() khi bạn không chắc chuỗi con có tồn tại hay không và muốn xử lý trường hợp không tìm thấy một cách nhẹ nhàng. Sử dụng index() khi bạn mong đợi chuỗi con phải có mặt và muốn chương trình dừng lại nếu không tìm thấy.

2. Thay thế chuỗi con: replace()

Phương thức này tạo ra một chuỗi mới bằng cách thay thế tất cả hoặc một số lần xuất hiện của chuỗi con cũ bằng chuỗi con mới.

Cú pháp: string.replace(old, new, count=-1)

  • old: Chuỗi con cần được thay thế.
  • new: Chuỗi con dùng để thay thế.
  • count (tùy chọn): Số lần thay thế tối đa. Nếu bỏ qua hoặc đặt là -1, tất cả các lần xuất hiện sẽ được thay thế.

Quan trọng: Chuỗi trong Python là bất biến (immutable). replace() không thay đổi chuỗi gốc, mà trả về một chuỗi mới đã được thay thế.

my_string = "Python là ngôn ngữ dễ học, Python rất mạnh mẽ."

# Thay thế tất cả 'Python' bằng 'Java'
new_string_1 = my_string.replace("Python", "Java")
print(f"Chuỗi sau khi thay thế tất cả: '{new_string_1}'") 
# Output: Chuỗi sau khi thay thế tất cả: 'Java là ngôn ngữ dễ học, Java rất mạnh mẽ.'

# Chỉ thay thế lần xuất hiện đầu tiên của 'Python'
new_string_2 = my_string.replace("Python", "Java", 1)
print(f"Chuỗi sau khi thay thế lần đầu: '{new_string_2}'")
# Output: Chuỗi sau khi thay thế lần đầu: 'Java là ngôn ngữ dễ học, Python rất mạnh mẽ.'

print(f"Chuỗi gốc không đổi: '{my_string}'")
# Output: Chuỗi gốc không đổi: 'Python là ngôn ngữ dễ học, Python rất mạnh mẽ.'

Giải thích: Ví dụ đầu tiên thay thế cả hai "Python". Ví dụ thứ hai chỉ thay thế "Python" đầu tiên do count=1. Chuỗi my_string ban đầu vẫn giữ nguyên giá trị.

3. Thay đổi kiểu chữ: upper(), lower(), capitalize(), title()

Các phương thức này giúp bạn dễ dàng chuyển đổi kiểu chữ của chuỗi:

  • upper(): Chuyển tất cả ký tự thành chữ hoa.
  • lower(): Chuyển tất cả ký tự thành chữ thường.
  • capitalize(): Chuyển ký tự đầu tiên của chuỗi thành chữ hoa, các ký tự còn lại thành chữ thường.
  • title(): Chuyển ký tự đầu tiên của mỗi từ thành chữ hoa, các ký tự khác trong từ thành chữ thường.
my_string = "lẬp tRÌnH pYTHON tHật vUI!"

print(f"UPPER: {my_string.upper()}")       # Output: UPPER: LẬP TRÌNH PYTHON THẬT VUI!
print(f"lower: {my_string.lower()}")       # Output: lower: lập trình python thật vui!
print(f"Capitalize: {my_string.capitalize()}") # Output: Capitalize: Lập trình python thật vui!
print(f"Title: {my_string.title()}")       # Output: Title: Lập Trình Python Thật Vui!

Giải thích: Mỗi phương thức trả về một chuỗi mới với kiểu chữ đã được thay đổi theo quy tắc tương ứng.

4. Loại bỏ khoảng trắng: strip(), lstrip(), rstrip()

Thường dùng để "làm sạch" dữ liệu đầu vào, loại bỏ các khoảng trắng hoặc ký tự không mong muốn ở hai đầu chuỗi.

  • strip([chars]): Loại bỏ các ký tự chars (mặc định là khoảng trắng) ở cả hai đầu chuỗi.
  • lstrip([chars]): Loại bỏ các ký tự charsđầu bên trái (leading) của chuỗi.
  • rstrip([chars]): Loại bỏ các ký tự charsđầu bên phải (trailing) của chuỗi.
my_string = "   \t  Nhiều khoảng trắng quá!   \n "
cleaned_strip = my_string.strip()
print(f"strip(): '{cleaned_strip}'") # Output: strip(): 'Nhiều khoảng trắng quá!'

cleaned_lstrip = my_string.lstrip()
print(f"lstrip(): '{cleaned_lstrip}'") # Output: lstrip(): 'Nhiều khoảng trắng quá!   \n '

cleaned_rstrip = my_string.rstrip()
print(f"rstrip(): '{cleaned_rstrip}'") # Output: rstrip(): '   \t  Nhiều khoảng trắng quá!'

# Loại bỏ ký tự cụ thể
url = "!!!!www.example.com????"
cleaned_url = url.strip('!?') 
print(f"strip('!?'): '{cleaned_url}'") # Output: strip('!?'): 'www.example.com'

Giải thích: strip() loại bỏ khoảng trắng, tab (\t), newline (\n) ở cả hai đầu. lstrip() chỉ loại bỏ ở đầu, rstrip() chỉ loại bỏ ở cuối. Ví dụ cuối cho thấy cách dùng strip() để loại bỏ các ký tự !? ở hai đầu chuỗi url.

5. Tách chuỗi: split()

Phương thức này cực kỳ hữu ích để chia một chuỗi thành một danh sách (list) các chuỗi con, dựa trên một ký tự phân tách (delimiter).

Cú pháp: string.split(separator=None, maxsplit=-1)

  • separator (tùy chọn): Ký tự hoặc chuỗi dùng để phân tách. Nếu bỏ qua hoặc là None, split() sẽ tách chuỗi dựa trên khoảng trắng (bao gồm dấu cách, tab, newline) và bỏ qua các chuỗi rỗng.
  • maxsplit (tùy chọn): Số lần tách tối đa. Nếu là -1 (mặc định), không có giới hạn.
sentence = "Đây là một câu ví dụ đơn giản"
words = sentence.split() # Tách theo khoảng trắng (mặc định)
print(f"Tách theo khoảng trắng: {words}") 
# Output: Tách theo khoảng trắng: ['Đây', 'là', 'một', 'câu', 'ví', 'dụ', 'đơn', 'giản']

csv_data = "Tên,Tuổi,ThànhPhố"
fields = csv_data.split(',') # Tách theo dấu phẩy
print(f"Tách theo dấu phẩy: {fields}")
# Output: Tách theo dấu phẩy: ['Tên', 'Tuổi', 'ThànhPhố']

long_string = "Một hai ba bốn năm sáu bảy"
# Chỉ tách 2 lần đầu tiên
parts = long_string.split(' ', 2) 
print(f"Tách tối đa 2 lần: {parts}")
# Output: Tách tối đa 2 lần: ['Một', 'hai', 'ba bốn năm sáu bảy']

Giải thích: split() trả về một danh sách các chuỗi con. Ví dụ đầu tách theo khoảng trắng. Ví dụ thứ hai tách dữ liệu CSV bằng dấu phẩy. Ví dụ cuối dùng maxsplit=2, nên chuỗi chỉ được tách thành 3 phần (2 lần tách): phần tử đầu, phần tử thứ hai, và phần còn lại của chuỗi.

6. Nối chuỗi từ danh sách: join()

Phương thức này làm ngược lại với split(). Nó nối các phần tử của một iterable (ví dụ: list, tuple) thành một chuỗi duy nhất, sử dụng chuỗi gọi phương thức join() làm ký tự nối (separator).

Cú pháp: separator.join(iterable)

  • separator: Chuỗi sẽ được chèn vào giữa các phần tử của iterable.
  • iterable: Một đối tượng có thể lặp qua (như list, tuple) chứa các chuỗi cần nối. Lưu ý: Tất cả các phần tử trong iterable phải là chuỗi.
word_list = ['Học', 'Python', 'thật', 'thú', 'vị']

# Nối các từ bằng dấu cách
sentence = ' '.join(word_list)
print(f"Nối bằng dấu cách: '{sentence}'") 
# Output: Nối bằng dấu cách: 'Học Python thật thú vị'

# Nối bằng dấu gạch nối
hyphenated = '-'.join(word_list)
print(f"Nối bằng gạch nối: '{hyphenated}'")
# Output: Nối bằng gạch nối: 'Học-Python-thật-thú-vị'

# Nối các ký tự
chars = ['P', 'y', 't', 'h', 'o', 'n']
python_word = ''.join(chars) # Dùng chuỗi rỗng làm ký tự nối
print(f"Nối ký tự: '{python_word}'")
# Output: Nối ký tự: 'Python'

Giải thích: Chuỗi gọi phương thức join() (ví dụ: ' ', '-', '') được sử dụng làm "keo" để gắn kết các phần tử trong danh sách word_list hoặc chars lại với nhau.


Việc thành thạo các phương thức chuỗi này sẽ giúp bạn xử lý văn bản, dữ liệu dạng chuỗi một cách nhanh chóng và chuyên nghiệp hơn rất nhiều trong các dự án Python của mình. Hãy thử nghiệm với các ví dụ và áp dụng chúng vào các bài toán thực tế để ghi nhớ và hiểu sâu hơn nhé!

Comments

There are no comments at the moment.