Hướng dẫn về mảng trong Python

Hướng dẫn về mảng trong Python

Giới thiệu

Hãy tưởng tượng bạn có một danh sách các bài hát yêu thích trên điện thoại. Danh sách phát này là danh sách trong đó mỗi bài hát được sắp xếp theo một thứ tự cụ thể. Bạn có thể phát bài hát đầu tiên, chuyển sang bài thứ hai, chuyển sang bài thứ năm, v.v. Danh sách phát này rất giống một mảng trong lập trình máy tính.

Mảng là một trong những cấu trúc dữ liệu cơ bản và được sử dụng rộng rãi nhất.

Về bản chất, mảng là một cách có cấu trúc để lưu trữ nhiều mục (như số, ký tự hoặc thậm chí các mảng khác) theo một thứ tự cụ thể và bạn có thể nhanh chóng truy cập, sửa đổi hoặc xóa bất kỳ mục nào nếu bạn biết vị trí (chỉ mục) của nó.

Trong hướng dẫn này, chúng tôi sẽ cung cấp cho bạn cái nhìn tổng quan toàn diện về cấu trúc dữ liệu mảng. Trước hết, chúng ta sẽ xem mảng là gì và đặc điểm chính của chúng là gì. Sau đó, chúng ta sẽ chuyển sang thế giới Python, khám phá cách triển khai, thao tác và áp dụng mảng trong các tình huống thực tế.

Hiểu cấu trúc dữ liệu mảng

Mảng là một trong những cấu trúc dữ liệu cơ bản và lâu đời nhất được sử dụng trong khoa học máy tính và lập trình. Sự đơn giản của chúng, kết hợp với tính hiệu quả trong một số hoạt động nhất định, khiến chúng trở thành chủ đề chính cho bất kỳ ai tìm hiểu sâu về lĩnh vực quản lý và thao tác dữ liệu.

Mảng là một tập hợp các phần tử, thường là cùng loại, được lưu trữ trong vị trí bộ nhớ liền kề.

Bộ lưu trữ liền kề này cho phép các mảng cung cấp quyền truy cập liên tục vào bất kỳ phần tử nào, dựa trên chỉ mục của nó. Mỗi mục trong một mảng được gọi là một thành phầnvà vị trí của một phần tử trong mảng được xác định bởi chỉ số, thường là bắt đầu từ số không.

Ví dụ, hãy xem xét một mảng các số nguyên: [10, 20, 30, 40, 50]. Ở đây, phần tử 20 có chỉ số là 1:

lập chỉ mục mảng python

Có nhiều lợi thế về việc sử dụng mảng để lưu trữ dữ liệu của chúng tôi. Ví dụ, do cách bố trí bộ nhớ, mảng cho phép O (1) (không đổi) độ phức tạp về thời gian khi truy cập một phần tử theo chỉ mục của nó. Điều này đặc biệt có lợi khi chúng ta cần truy cập ngẫu nhiên vào các phần tử. Ngoài ra, mảng được lưu trữ trong vị trí bộ nhớ liền kề, điều này có thể dẫn đến vị trí bộ đệm tốt hơn và cải thiện hiệu suất tổng thể trong một số hoạt động nhất định. Một ưu điểm đáng chú ý khác của việc sử dụng mảng là vì mảng có kích thước cố định sau khi được khai báo nên việc quản lý bộ nhớ sẽ dễ dàng hơn và tránh lỗi tràn bộ nhớ hoặc lỗi hết bộ nhớ không mong muốn.

Chú thích: Mảng đặc biệt hữu ích trong các tình huống trong đó kích thước của bộ sưu tập được biết trước và không đổihoặc nơi truy cập ngẫu nhiên thường xuyên hơn việc chèn và xóa.

Mặt khác, mảng có tập hợp riêng hạn chế. Một trong những hạn chế chính của mảng truyền thống là chúng kích thước cố định. Khi một mảng được tạo, kích thước của nó không thể thay đổi. Điều này có thể dẫn đến các vấn đề như lãng phí bộ nhớ (nếu mảng quá lớn) hoặc cần phải thay đổi kích thước (nếu mảng quá nhỏ). Ngoài ra, việc chèn hoặc xóa một phần tử vào giữa mảng đòi hỏi phải dịch chuyển các phần tử, dẫn đến O (n) độ phức tạp về thời gian cho các hoạt động này.

Để tổng hợp tất cả những điều này, hãy minh họa các đặc điểm chính của mảng bằng ví dụ về danh sách bài hát ở đầu hướng dẫn này. Mảng là một cấu trúc dữ liệu:

  • Được lập chỉ mục: Giống như mỗi bài hát trong danh sách phát của bạn đều có một số (1, 2, 3,…), mỗi phần tử trong một mảng đều có một chỉ mục. Tuy nhiên, trong hầu hết các ngôn ngữ lập trình, chỉ mục bắt đầu từ 0. Vì vậy, mục đầu tiên ở chỉ mục 0, mục thứ hai ở chỉ mục 1, v.v.

  • Có kích thước cố định: Khi bạn tạo danh sách phát cho 10 bài hát, bạn không thể thêm bài hát thứ 11 mà không xóa bài hát trước. Tương tự, mảng có kích thước cố định. Khi bạn tạo một mảng có kích thước nhất định, bạn không thể thêm nhiều mục hơn dung lượng của nó.

  • đồng nhất: Tất cả các bài hát trong danh sách phát của bạn đều là bản nhạc. Tương tự, tất cả các phần tử trong mảng đều có cùng kiểu. Nếu bạn có một mảng số nguyên, bạn không thể đột nhiên lưu trữ một chuỗi văn bản trong đó.

  • Có quyền truy cập trực tiếp: Nếu bạn muốn nghe bài hát thứ 7 trong danh sách phát của mình, bạn có thể chuyển trực tiếp đến bài hát đó. Tương tự, với mảng, bạn có thể truy cập ngay vào bất kỳ phần tử nào nếu bạn biết chỉ mục của nó.

  • Bộ nhớ liền kề: Cái này mang tính kỹ thuật hơn một chút. Khi một mảng được tạo trong bộ nhớ máy tính, nó sẽ chiếm một khối bộ nhớ liên tục. Hãy tưởng tượng nó giống như một dãy tủ đựng đồ liền kề trong trường. Mỗi tủ khóa nằm cạnh nhau, không có khoảng trống ở giữa.

Python và mảng

Python, được biết đến với tính linh hoạt và dễ sử dụng, cung cấp nhiều cách để làm việc với mảng. Mặc dù Python không có cấu trúc dữ liệu mảng gốc như một số ngôn ngữ khác, nhưng nó cung cấp các lựa chọn thay thế mạnh mẽ có thể hoạt động tương tự và thậm chí còn cung cấp các khả năng mở rộng.

Ngay cái nhìn đầu tiên, danh sách của Python có thể dường như đồng nghĩa với một mảng, nhưng có những khác biệt và sắc thái tinh tế cần xem xét:

Danh sách Mảng
Cấu trúc dữ liệu Python tích hợp Không có nguồn gốc từ Python – chúng đến từ mô-đun `array`
Kích thước động Kích thước cố định (được xác định trước)
Có thể chứa các mục thuộc loại dữ liệu khác nhau Giữ các vật phẩm cùng loại
Cung cấp một loạt các phương pháp tích hợp để thao tác Cần nhập mô-đun bên ngoài
Độ phức tạp về thời gian O(1) cho các hoạt động truy cập Độ phức tạp về thời gian O(1) cho các hoạt động truy cập
Tiêu thụ nhiều bộ nhớ hơn Bộ nhớ hiệu quả hơn

Nhìn vào bảng này, tự nhiên tôi phải hỏi – “Khi nào nên sử dụng cái nào?”. Chà, nếu bạn cần một bộ sưu tập có thể tăng hoặc giảm linh hoạt và có thể chứa các loại dữ liệu hỗn hợp, thì danh sách của Python là lựa chọn phù hợp. Tuy nhiên, đối với các trường hợp yêu cầu bộ sưu tập tiết kiệm bộ nhớ hơn với các phần tử cùng loại, bạn có thể cân nhắc sử dụng Python array module hoặc các thư viện bên ngoài như NumPy.

Sản phẩm mảng Mô-đun trong Python

Khi hầu hết các nhà phát triển nghĩ về mảng trong Python, họ thường nghĩ về danh sách. Tuy nhiên, Python cung cấp một cấu trúc mảng chuyên biệt hơn thông qua tính năng tích hợp sẵn của nó. array mô-đun. Mô-đun này cung cấp khả năng lưu trữ hiệu quả về không gian cho các kiểu dữ liệu kiểu C cơ bản trong Python.

Mặc dù danh sách Python cực kỳ linh hoạt và có thể lưu trữ bất kỳ loại đối tượng nào, nhưng đôi khi chúng có thể quá mức cần thiết, đặc biệt khi bạn chỉ cần lưu trữ một tập hợp các kiểu dữ liệu cơ bản, như số nguyên hoặc số float. Các array mô-đun cung cấp cách tạo mảng có hiệu quả bộ nhớ cao hơn danh sách cho các loại dữ liệu cụ thể.

Tạo một mảng

Để sử dụng array mô-đun, trước tiên bạn cần nhập nó:

from array import array

Sau khi nhập, bạn có thể tạo một mảng bằng cách sử dụng array() người xây dựng:

arr = array('i', [1, 2, 3, 4, 5])
print(arr)

Ở đây, 'i' đối số chỉ ra rằng mảng sẽ lưu trữ đã ký số nguyên. Có một số mã loại khác có sẵn, chẳng hạn như 'f' cho phao và 'd' cho đôi.

Truy cập và sửa đổi các phần tử

Bạn có thể truy cập và sửa đổi các phần tử trong một mảng giống như cách bạn làm với một danh sách:

print(arr[2]) 

Và bây giờ, hãy sửa đổi phần tử bằng cách thay đổi giá trị của nó thành 6:

arr[2] = 6
print(arr) 

Phương thức mảng

Sản phẩm array module cung cấp một số phương thức để thao tác mảng:

  • append() – Thêm một phần tử vào cuối mảng:

    arr.append(7)
    print(arr) 
  • extend() – Nối các phần tử có thể lặp lại vào cuối:

    arr.extend([8, 9])
    print(arr) 
  • pop() – Loại bỏ và trả về phần tử tại vị trí đã cho:

    arr.pop(2)
    print(arr) 
  • remove(): Loại bỏ lần xuất hiện đầu tiên của giá trị được chỉ định:

    arr.remove(2)
    print(arr) 
  • reverse(): Đảo ngược thứ tự của mảng:

    arr.reverse()
    print(arr) 

Lưu ý: Có nhiều phương pháp hơn chúng tôi liệt kê ở đây. Tham khảo đến tài liệu Python chính thức để xem danh sách tất cả các phương pháp có sẵn trong array mô-đun.

Trong khi array mô-đun cung cấp một cách hiệu quả hơn về bộ nhớ để lưu trữ các loại dữ liệu cơ bản, điều cần thiết là phải nhớ nó hạn chế. Không giống như danh sách, mảng đồng nhất. Điều này có nghĩa là tất cả các phần tử trong mảng phải cùng loại. Ngoài ra, bạn chỉ có thể lưu trữ các kiểu dữ liệu kiểu C cơ bản trong mảng. Nếu cần lưu trữ các đối tượng tùy chỉnh hoặc các loại Python khác, bạn sẽ cần sử dụng danh sách hoặc cấu trúc dữ liệu khác.

Mảng NumPy

NumPy, viết tắt của Numerical Python, là gói nền tảng để tính toán số trong Python. Một trong những tính năng chính của nó là sức mạnh Đối tượng mảng N chiều, cung cấp các thao tác nhanh trên mảng, bao gồm toán học, logic, thao tác hình dạng, v.v.

Mảng NumPy linh hoạt hơn mảng tích hợp sẵn của Python array mô-đun và là thành phần chính trong các dự án khoa học dữ liệu và học máy.

Tại sao nên sử dụng mảng NumPy?

Điều đầu tiên nghĩ đến là hiệu suất. Mảng NumPy được triển khai trong C và cho phép lưu trữ bộ nhớ hiệu quả cũng như hoạt động nhanh hơn nhờ các thuật toán được tối ưu hóa và lợi ích của việc lưu trữ bộ nhớ liền kề.

Trong khi các danh sách và mảng tích hợp của Python là một chiều, mảng NumPy có thể đa chiều, khiến chúng trở nên lý tưởng để biểu diễn ma trận hoặc tensor.

Xem hướng dẫn thực hành, thực tế của chúng tôi để học Git, với các phương pháp hay nhất, các tiêu chuẩn được ngành công nghiệp chấp nhận và bảng lừa đảo đi kèm. Dừng lệnh Googling Git và thực sự học nó!

Cuối cùng, NumPy cung cấp một hàng loạt các chức năng để thao tác trên các mảng này, từ số học cơ bản đến các phép toán nâng cao, định hình lại, phân tách, v.v.

Lưu ý: Khi bạn biết trước kích thước của dữ liệu, việc phân bổ trước bộ nhớ cho mảng (đặc biệt là trong NumPy) có thể dẫn đến cải thiện hiệu suất.

Tạo một mảng NumPy

Để sử dụng NumPy, trước tiên bạn cần cài đặt nó (pip install numpy) và sau đó nhập nó:

import numpy as np

Sau khi nhập, bạn có thể tạo mảng NumPy bằng cách sử dụng array() chức năng:

arr = np.array([1, 2, 3, 4, 5])
print(arr) 

Bạn cũng có thể tạo mảng đa chiều:

matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix)

Điều này sẽ cung cấp cho chúng tôi:

[[1 2 3] [4 5 6] [7 8 9]]

Bên cạnh những cách cơ bản để tạo mảng, NumPy còn cung cấp cho chúng ta những cách thông minh khác để tạo mảng. Một trong số đó là arange() phương pháp. Nó tạo ra các mảng có giá trị tăng dần đều đặn:

arr = np.arange(10)
print(arr) 

Một cái khác là linspace() phương thức tạo các mảng có số phần tử được chỉ định, cách đều nhau giữa các giá trị bắt đầu và kết thúc được chỉ định:

even_space = np.linspace(0, 1, 5)
print(even_space) 

Truy cập và sửa đổi các phần tử

Việc truy cập và sửa đổi các phần tử trong mảng NumPy rất trực quan:

print(arr[2]) arr[2] = 6
print(arr) 

Thực hiện khá giống nhau đối với mảng đa chiều:

print(matrix[1, 2]) matrix[1, 2] = 10
print(matrix)

Sẽ thay đổi giá trị của phần tử ở hàng thứ hai (chỉ mục 1) và cột thứ ba (chỉ mục 2):

[[1 2 3] [4 5 20] [7 8 9]]

Thay đổi hình dạng của một mảng

NumPy cung cấp nhiều hàm và phương thức để thao tác và vận hành trên mảng. Ví dụ: bạn có thể sử dụng reshape() phương pháp để thay đổi hình dạng của một mảng. Giả sử chúng ta có một mảng đơn giản:

import numpy as np arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
print("Original Array:")
print(arr) 

Và chúng tôi muốn định hình lại nó thành ma trận 3×4. Tất cả những gì bạn cần làm là sử dụng reshape() phương thức có kích thước mong muốn được truyền dưới dạng đối số:


reshaped_arr = arr.reshape(3, 4)
print("Reshaped Array (3x4):")
print(reshaped_arr)

Điều này sẽ dẫn đến:

Reshaped Array (3x4):
[[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12]]

Phép nhân ma trận

Sản phẩm numpy.dot() phương pháp được sử dụng cho Phép nhân ma trận. Nó trả về tích số chấm của hai mảng. Đối với mảng một chiều, đó là sản phẩm bên trong của các mảng. Đối với mảng 2 chiều, nó tương đương với Phép nhân ma trận, và đối với ND, nó là một tổng sản phẩm trên trục cuối cùng của mảng đầu tiên và từ thứ hai đến cuối cùng của mảng thứ hai.

Hãy xem nó hoạt động như thế nào. Đầu tiên, hãy tính tích vô hướng của hai mảng 1-D (tích bên trong của vectơ):

import numpy as np vec1 = np.array([1, 2, 3])
vec2 = np.array([4, 5, 6])
dot_product_1d = np.dot(vec1, vec2) print("Dot product of two 1-D arrays:")
print(dot_product_1d) 

Điều này sẽ dẫn đến:

Dot product of two 1-D arrays:
32

32 trên thực tế là tích bên trong của hai mảng – (14 + 25 + 3*6). Tiếp theo, chúng ta có thể thực hiện phép nhân ma trận của hai mảng 2-D:


mat1 = np.array([[1, 2], [3, 4]])
mat2 = np.array([[2, 0], [1, 3]])
matrix_product = np.dot(mat1, mat2) print("Matrix multiplication of two 2-D arrays:")
print(matrix_product) 

Điều đó sẽ cung cấp cho chúng tôi:

Matrix multiplication of two 2-D arrays:
[[ 4 6] [10 12]]

Mảng NumPy là một bước tiến đáng kể so với danh sách cài sẵn của Python và array mô-đun, đặc biệt là cho các tính toán khoa học và toán học. Tính hiệu quả của chúng, kết hợp với chức năng phong phú do thư viện NumPy cung cấp, khiến chúng trở thành công cụ không thể thiếu cho bất kỳ ai muốn thực hiện các phép tính số trong Python.

Kết luận

Mảng, nền tảng của khoa học máy tính và lập trình, đã nhiều lần chứng minh giá trị của chúng trên nhiều ứng dụng và lĩnh vực khác nhau. Trong Python, cấu trúc dữ liệu cơ bản này, thông qua các dạng khác nhau như danh sách, array mô-đun và mảng NumPy mạnh mẽ, mang đến cho các nhà phát triển sự kết hợp giữa hiệu quả, tính linh hoạt và sự đơn giản.

Trong suốt hướng dẫn này, chúng ta đã đi từ các khái niệm cơ bản về mảng đến các ứng dụng thực tế của chúng trong Python. Chúng ta đã thấy các mảng, với tính chất liền kề trong bộ nhớ, cung cấp thời gian truy cập nhanh chóng như thế nào và danh sách động của Python mang lại một lớp linh hoạt bổ sung như thế nào. Chúng tôi cũng đã đi sâu vào thế giới chuyên biệt của NumPy, nơi các mảng biến thành các công cụ mạnh mẽ để tính toán số.

Dấu thời gian:

Thêm từ xếp chồng lên nhau