Python - Immutable Data Structures

Các Immutable data structures trong Python là các cấu trúc dữ liệu mà một khi được tạo ra, không thể thay đổi. Điều này có nghĩa là bất kỳ nỗ lực nào để sửa đổi cấu trúc dữ liệu sẽ dẫn đến việc tạo ra một thể hiện mới thay vì thay đổi bản gốc. Các cấu trúc dữ liệu không thay đổi rất hữu ích để đảm bảo rằng dữ liệu vẫn không thay đổi trong suốt quá trình thực thi của một chương trình, điều này có thể giúp ngăn ngừa lỗi và làm cho mã dễ hiểu và duy trì hơn.

Trước khi đi sâu vào chủ đề này, hãy cùng ôn lại nhanh về what is datastructure? . Các cấu trúc dữ liệu là định dạng chuyên biệt để tổ chức, xử lý, truy xuất và lưu trữ dữ liệu. Chúng xác định cách dữ liệu được sắp xếp trong bộ nhớ và cách các thao tác như truy cập, chèn, xóa và cập nhật có thể được thực hiện một cách hiệu quả.

Different Immutable Data Structures in Python

Các cấu trúc dữ liệu bất biến là rất quan trọng trong Python vì tính ổn định, an toàn cho luồng và dễ sử dụng. Dưới đây là các cấu trúc dữ liệu bất biến khác nhau trong Python −

  • Tuples : These are the ordered collections of items that cannot be changed after their creation. They can contain mixed data types and are useful for representing fixed collections of related items.
  • Strings : These Data structures are sequences of characters and are immutable. Any operation that modifies a string will create a new string.
  • Frozensets: These are immutable versions of sets. Unlike regular sets, frozensets do not allow modification after creation.
  • Named Tuples: These are a subclass of tuples with named fields which provide more readable and self-documenting code. They are immutable like regular tuples.

Bây giờ, hãy tiến hành nói về từng cấu trúc dữ liệu không thay đổi một cách chi tiết.

Tuples

Tuple trong Python là các chuỗi phần tử không thể thay đổi, có nghĩa là một khi được tạo ra, chúng không thể được sửa đổi. Chúng được định nghĩa bằng cách sử dụng dấu ngoặc đơn '()' và có thể chứa một tập hợp các mục như số, chuỗi và thậm chí là các tuple khác.

Creating Tuples

Các tuple được tạo ra bằng cách sử dụng dấu ngoặc đơn '()' và các phần tử được phân tách bằng dấu phẩy ','. Ngay cả các tuple chỉ có một phần tử cũng cần có dấu phẩy ở cuối để phân biệt chúng với các biểu thức nhóm.

Dưới đây là ví dụ về việc tạo một tuple bằng cách gán dấu ngoặc đơn '()' cho một biến −

empty_tuple = ()
single_element_tuple = (5,)  # Note the comma after the single element
print("Single element tuple:", single_element_tuple)
multi_element_tuple = (1, 2, 'Tutorialspoint', 3.14)
print("Multi elements tuple:", multi_element_tuple)
nested_tuple = (1, (2, 3), 'Learning')
print("Nested tuple:", nested_tuple)

Khi thực thi đoạn mã trên, chúng ta sẽ nhận được output

Single element tuple: (5,)
Multi elements tuple: (1, 2, 'Tutorialspoint', 3.14)
Nested tuple: (1, (2, 3), 'Learning')

Understanding Tuple Immutability in Python

Dưới đây, chúng ta sẽ hiểu về tính bất biến của tuple trong Python. Dưới đây là ví dụ -

# Define a tuple
my_tuple = (1, 2, 3, 'hello')
# Attempt to modify an element (which is not possible with tuples)
# This will raise a TypeError
try:
   my_tuple[0] = 10
except TypeError as e:
   print(f"Error: {e}")
# Even trying to append or extend a tuple will result in an error
try:
   my_tuple.append(4)
except AttributeError as e:
   print(f"Error: {e}")
# Trying to reassign the entire tuple to a new value is also not allowed
try:
   my_tuple = (4, 5, 6)
except TypeError as e:
   print(f"Error: {e}")
print("Original tuple:", my_tuple)

Khi thực thi đoạn mã trên, chúng ta sẽ nhận được output

Error: 'tuple' object does not support item assignment
Error: 'tuple' object has no attribute 'append'
Original tuple: (4, 5, 6)

Strings

Chuỗi trong Python là các dãy ký tự được sử dụng để đại diện và thao tác với dữ liệu văn bản. Chúng được bao quanh bởi dấu nháy đơn ' hoặc dấu nháy kép " với tùy chọn sử dụng dấu nháy ba """ cho các chuỗi nhiều dòng.

Các đặc điểm chính bao gồm tính không thay đổi, có nghĩa là một khi được tạo ra, những chuỗi này không thể bị thay đổi, chỉ số có thứ tự nơi các ký tự được truy cập theo vị trí và hỗ trợ cho nhiều thao tác khác nhau như nối chuỗi, cắt và lặp.

Chuỗi (Strings) là cơ bản trong Python cho các tác vụ như xử lý văn bản, các thao tác nhập/xuất và đại diện dữ liệu trong các ứng dụng, cung cấp một bộ công cụ linh hoạt với các phương thức tích hợp sẵn để thao tác và định dạng thông tin văn bản một cách hiệu quả.

Creating Strings

Mỗi loại phương thức tạo chuỗi, tức là ', ", """ đều có trường hợp sử dụng riêng của nó tùy thuộc vào việc chúng ta cần bao gồm dấu ngoặc kép trong chuỗi, xử lý văn bản nhiều dòng hoặc các yêu cầu định dạng cụ thể khác trong mã Python của chúng ta.

Dưới đây là ví dụ về việc tạo chuỗi với sự trợ giúp của ba loại dấu ngoặc đơn ', ", """ −

# Single line string
single_quoted_string = 'Hello, Welcome to Tutorialspoint'

# Double quoted string
double_quoted_string = "Python Programming"

# Triple quoted string for multi-line strings
multi_line_string = """This is a 
multi-line 
string"""

print(single_quoted_string)
print(double_quoted_string)
print(multi_line_string)

Khi thực thi đoạn mã trên, chúng ta sẽ nhận được output

Hello, Welcome to Tutorialspoint
Python Programming
This is a
multi-line
string

Understanding String Immutability in Python

Với sự trợ giúp của ví dụ sau, chúng ta sẽ hiểu về tính bất biến của chuỗi trong Python.

# Example demonstrating string immutability
my_string = "Hello"

# Attempting to modify a string will create a new string instead of modifying the original
modified_string = my_string + " Learners"
print(modified_string)  # Output: Hello Learners

# Original string remains unchanged
print(my_string)  # Output: Hello

# Trying to modify the string directly will raise an error
try:
   my_string[0] = 'h'  # TypeError: 'str' object does not support item assignment
except TypeError as e:
   print(f"Error: {e}")

Khi thực thi đoạn mã trên, chúng ta sẽ nhận được output

Hello Learners
Hello
Error: 'str' object does not support item assignment

Frozen Sets

Một tập hợp đông lạnh (frozen set) trong Python là phiên bản không thay đổi (immutable) của một tập hợp (set). Khi đã được tạo, các phần tử của nó không thể bị thay đổi, thêm mới hoặc xóa bỏ. Tập hợp đông lạnh rất hữu ích trong các tình huống mà chúng ta cần một tập hợp giữ nguyên trong suốt quá trình thực thi của chương trình, đặc biệt khi chúng ta muốn sử dụng nó làm khóa trong một từ điển (dictionary) hoặc như một phần tử trong một tập hợp khác.

Creating Frozen Sets

Chúng ta có thể tạo một tập hợp đông lạnh (frozen set) bằng cách sử dụng trình tạo frozenset() bằng cách truyền một đối tượng có thể lặp lại (iterable) như danh sách hoặc một tập hợp khác làm tham số. Dưới đây là ví dụ về việc tạo tập hợp đông lạnh −

# Creating a frozen set
fset = frozenset([1, 2, 3, 4])

# Printing the frozen set
print(fset)  

Khi thực thi đoạn mã trên, chúng ta sẽ nhận được output

frozenset({1, 2, 3, 4})

Understanding Frozen Sets Immutability in Python

Dưới đây là một ví dụ cho thấy cách mà frozensets không thay đổi và không cho phép sửa đổi sau khi được tạo.

# Creating a frozenset
frozen_set = frozenset([1, 2, 3, 4])

# Attempting to add an element to the frozenset will raise an error
try:
   frozen_set.add(5)
except AttributeError as e:
   print(f"Error: {e}")

# Attempting to remove an element from the frozenset will also raise an error
try:
   frozen_set.remove(2)
except AttributeError as e:
   print(f"Error: {e}")

# The original frozenset remains unchanged
print("Original frozenset:", frozen_set)  

Khi thực thi đoạn mã trên, chúng ta sẽ nhận được output

Error: 'frozenset' object has no attribute 'add'
Error: 'frozenset' object has no attribute 'remove'
Original frozenset: frozenset({1, 2, 3, 4})

Named Tuples

Một Named tuple trong Python là một cấu trúc dữ liệu nhẹ có sẵn trong mô-đun collections, hoạt động giống như một tuple nhưng cho phép chúng ta truy cập các phần tử của nó bằng cách sử dụng các thuộc tính có tên cũng như chỉ số.

Nó kết hợp các lợi thế của tuples như không thể thay đổi, tiết kiệm bộ nhớ với khả năng tham chiếu đến các phần tử bằng tên, nâng cao khả năng đọc và duy trì của mã.

Creating Named Tuples

Chúng ta có thể định nghĩa một tuple có tên bằng cách sử dụng hàm namedtuple() từ mô-đun collections. Nó nhận hai đối số, đó là một tên cho loại tuple có tên và một chuỗi, tức là chuỗi tên trường hoặc iterable của các chuỗi, xác định tên của các trường của nó.

from collections import namedtuple

# Define a named tuple type 'Point' with fields 'x' and 'y'
Point = namedtuple('Point', ['x', 'y'])

# Create an instance of Point
p1 = Point(1, 2)

# Access elements by index (like a tuple)
print(p1[0])  

# Access elements by name
print(p1.x)   
print(p1.y)   

Khi thực thi đoạn mã trên, chúng ta sẽ nhận được output

1
1
2

Understanding Named Tuples Immutability in Python

Các tuple đã đặt tên trong Python được cung cấp bởi các hàm factory collections.namedtuple thực sự là bất biến. Chúng hoạt động tương tự như các tuple thông thường nhưng có các trường được đặt tên, giúp chúng dễ đọc hơn và tự tài liệu hóa.

from collections import namedtuple

# Define a named tuple called Point with fields 'x' and 'y'
Point = namedtuple('Point', ['x', 'y'])

# Create an instance of Point
p = Point(x=1, y=2)
print(p)  
# Attempt to modify the named tuple
# This will raise an AttributeError since named tuples are immutable
try:
   p.x = 10
except AttributeError as e:
   print(f"Error occurred: {e}")  

# Accessing elements in a named tuple is similar to accessing elements in a regular tuple
print(p.x) 
print(p.y) 

Khi thực thi đoạn mã trên, chúng ta sẽ nhận được output

Point(x=1, y=2)
Error occurred: can't set attribute
1
2