Python có thể băm

Là ngôn ngữ lập trình có mục đích chung, Python cung cấp nhiều loại dữ liệu tích hợp sẵn cho các trường hợp sử dụng khác nhau

Khi bạn học những điều cơ bản này, có lẽ bạn đã gặp phải đề cập đến hashable tại một số điểm nhất định. Ví dụ: bạn có thể thấy rằng các khóa trong dict cần có thể băm được [xem một ví dụ nhỏ trong đoạn mã bên dưới]

Ví dụ khác, có đề cập rằng các phần tử trong set cần phải được băm

Bạn có thể thắc mắc — Hashable chính xác có nghĩa là gì? . Nhiều câu hỏi liên quan có thể được hỏi

Trong bài viết này, chúng ta sẽ xem xét một số điểm chính về khả năng băm để bạn có thể tìm hiểu cách giải quyết những câu hỏi này. Cuối cùng, bạn có thể sẽ phát hiện ra rằng những câu hỏi này thực ra không khó chút nào, không giống như những gì bạn có thể nghĩ ban đầu.

Đối tượng nào có thể băm được và đối tượng nào không?

Trước khi chúng tôi bắt đầu bất kỳ lời giải thích cơ học nào, câu hỏi đầu tiên mà chúng tôi muốn giải quyết là đối tượng nào có thể băm được và đối tượng nào không.

Bởi vì chúng ta biết rằng Python yêu cầu rõ ràng rằng các phần tử trong một set phải có thể băm được, nên chúng ta có thể kiểm tra khả năng băm của một đối tượng bằng cách đơn giản là thử thêm đối tượng vào một set. Chèn thành công cho biết các đối tượng có thể băm và ngược lại

>>> # Create an empty set object
>>> elements = set[]
>>>
>>> # The list of objects with each to be inserted to the set
>>> items = [1, 0.1, 'ab', [2, 3], {'a': 1}, [1, 2], {2, 4}, None]

Như trong đoạn mã trên, tôi đã tạo một biến set có tên là elements và một biến list có tên là items, bao gồm các loại dữ liệu dựng sẵn được sử dụng phổ biến nhất. int, dict0, dict1, dict2, dict, list, set, và dict6

Thử nghiệm mà tôi sẽ thực hiện là thêm mỗi ________ 8 vào ________ 6. Tôi sẽ không sử dụng vòng lặp dict9 trong trường hợp này, bởi vì bất kỳ set0 nào có thể xảy ra sẽ dừng quá trình lặp lại. Thay vào đó, tôi sẽ chỉ truy xuất các mục riêng lẻ bằng cách lập chỉ mục

Như bạn có thể thấy trong đoạn mã trên, đây là tóm tắt nhanh về kết quả của thử nghiệm

Trả lời câu hỏi của phần

  • Các loại dữ liệu có thể băm. int, dict0, dict1, dict2 và dict6
  • Các kiểu dữ liệu không thể sửa đổi. dict, listset

Nếu bạn hoàn toàn mới lập trình Python, bạn có thể nhận thấy rằng ba loại dữ liệu không thể băm này đều có thể thay đổi về bản chất, trong khi năm loại dữ liệu có thể băm này đều là bất biến

Về bản chất, các dữ liệu có thể thay đổi này là các đối tượng có thể thay đổi giá trị sau khi tạo, trong khi giá trị của các đối tượng không thể thay đổi không thể thay đổi sau khi tạo

Khả năng thay đổi dữ liệu là một chủ đề độc lập mà tôi đã đề cập trước đây trong bài viết khác của mình

Hashable nghĩa là gì?

Bây giờ bạn có một số ý tưởng về đối tượng nào có thể băm được và đối tượng nào không, nhưng chính xác thì hàm băm có nghĩa là gì?

Trên thực tế, bạn có thể đã nghe nhiều thuật ngữ máy tính tương tự liên quan đến hashable, chẳng hạn như hash value, hashing, hash table và hashmap. Về cốt lõi, chúng chia sẻ cùng một quy trình cơ bản - băm

Quá trình băm chung [Wikipedia, Miền công cộng]

Sơ đồ trên cho bạn thấy quá trình băm chung. Chúng tôi bắt đầu với một số giá trị dữ liệu thô [được gọi là khóa trong hình]

Hàm băm, đôi khi được gọi là hàm băm, sẽ thực hiện các tính toán cụ thể và xuất các giá trị băm [được gọi là hàm băm trong hình] cho các giá trị dữ liệu thô

Băm và các khái niệm liên quan của nó cần cả một cuốn sách để làm rõ, điều này nằm ngoài phạm vi của bài viết hiện tại. Tuy nhiên, một số khía cạnh quan trọng đã được thảo luận ngắn gọn trong bài viết trước của tôi

Ở đây, tôi sẽ chỉ nhấn mạnh một số điểm chính có liên quan đến cuộc thảo luận hiện tại

  1. Hàm băm phải mạnh mẽ về mặt tính toán sao cho các đối tượng khác nhau sẽ có các giá trị băm khác nhau. Khi các đối tượng khác nhau có cùng giá trị băm, xung đột sẽ xảy ra [như trong hình trên] và cần được xử lý
  2. Hàm băm phải nhất quán sao cho các đối tượng giống nhau sẽ luôn dẫn đến các giá trị băm giống nhau

Python đã triển khai hàm băm tích hợp để tạo ra các giá trị băm cho các đối tượng của nó. Cụ thể, chúng ta có thể truy xuất giá trị băm của một đối tượng bằng cách sử dụng hàm set9 tích hợp. Đoạn mã sau đây cho bạn thấy một số ví dụ

Như được hiển thị ở trên, chúng tôi có thể nhận được các giá trị băm - số nguyên cho các đối tượng_______9 và dict2

Tuy nhiên, cả đối tượng list và đối tượng dict đều không có giá trị băm. Những kết quả này phù hợp với sự khác biệt mà chúng tôi đang thực hiện giữa các đối tượng có thể băm và không thể băm trong phần trước

Trả lời câu hỏi của phần

  • Có thể băm. Một đặc điểm của đối tượng Python để cho biết liệu đối tượng có giá trị băm hay không, cho phép đối tượng đóng vai trò là khóa trong từ điển hoặc thành phần trong tập hợp

Làm cách nào chúng ta có thể tùy chỉnh khả năng băm?

Tính linh hoạt của Python với tư cách là ngôn ngữ lập trình đa năng chủ yếu đến từ việc hỗ trợ tạo các lớp tùy chỉnh. Với các lớp của riêng bạn, nhiều dữ liệu và hoạt động liên quan có thể được nhóm theo cách dễ đọc và có ý nghĩa hơn nhiều

Điều quan trọng là Python đã phát triển đủ thông minh để làm cho các đối tượng tùy chỉnh của chúng ta có thể băm được theo mặc định trong hầu hết các trường hợp

Xem xét ví dụ sau. Chúng tôi đã tạo một lớp tùy chỉnh, set4, cho phép chúng tôi tạo các phiên bản bằng cách chỉ định tên và số an sinh xã hội của một người

Đáng chú ý, chúng tôi đã ghi đè hàm set5 mặc định bằng phương pháp f-string, điều này sẽ cho phép chúng tôi hiển thị đối tượng với thông tin dễ đọc hơn, như được hiển thị trong dòng cuối cùng của đoạn mã

Như được hiển thị trong đoạn mã trên, chúng ta có thể tìm ra giá trị băm cho đối tượng đã tạo set6 bằng cách sử dụng hàm set9 tích hợp. Điều quan trọng là chúng ta có thể bao gồm đối tượng set6 như một thành phần trong đối tượng set, điều này thật tốt

Tuy nhiên, điều gì sẽ xảy ra nếu chúng ta muốn thêm nhiều trường hợp set4 vào tập hợp?

Xem đoạn mã sau. Tôi đã tạo một phiên bản set4 khác, set4, có cùng tên và số an sinh xã hội — về cơ bản là cùng một thể nhân

Tuy nhiên, khi chúng tôi thêm người này vào đối tượng set, set6, cả hai đối tượng set4 đều ở trong set, điều mà chúng tôi không muốn xảy ra

Bởi vì, theo thiết kế, chúng tôi muốn đối tượng set lưu trữ những thể nhân duy nhất. Phù hợp với cả hai người được bao gồm trong đối tượng set, chúng tôi phát hiện ra rằng hai trường hợp set4 này thực sự khác nhau

Tôi sẽ chỉ cho bạn mã về cách chúng tôi có thể làm cho lớp tùy chỉnh set4 thông minh hơn để nó biết những người nào giống hoặc khác nhau, về vấn đề đó

Trong đoạn mã trên, chúng tôi đã cập nhật lớp tùy chỉnh set4 bằng cách ghi đè các hàm set4 và set5

Trước đây chúng tôi đã đề cập rằng hàm set6 được sử dụng để tính giá trị băm của một đối tượng. Hàm set7 được sử dụng để so sánh đối tượng này với đối tượng khác cho bằng nhau và nó cũng yêu cầu các đối tượng so sánh bằng nhau phải có cùng giá trị băm

Theo mặc định, các thể hiện của lớp tùy chỉnh được so sánh bằng cách so sánh danh tính của chúng bằng cách sử dụng hàm set8 tích hợp [tìm hiểu thêm về hàm set8 bằng cách tham khảo bài viết này]

Với cách triển khai được cập nhật, chúng ta có thể thấy rằng khi chúng ta cố gắng tạo một đối tượng set bao gồm hai đối tượng set4, hàm set6 được gọi sao cho đối tượng đã đặt chỉ giữ các đối tượng có giá trị băm duy nhất

Một điều khác cần lưu ý là khi Python kiểm tra xem các phần tử trong đối tượng set có giá trị băm duy nhất hay không, nó sẽ đảm bảo rằng các đối tượng này cũng không bằng nhau bằng cách gọi hàm set7

Trả lời câu hỏi của phần

tùy biến. Để cung cấp các hành vi tùy chỉnh về khả năng băm và bình đẳng, chúng tôi cần triển khai các hàm set4 và set5 trong các lớp tùy chỉnh của mình

Phần kết luận

Trong bài viết này, chúng ta đã xem xét các khái niệm về hashable/hashability trong Python

Cụ thể, bằng cách giải quyết ba câu hỏi quan trọng, tôi hy vọng rằng bạn hiểu rõ hơn về khả năng băm trong Python. Khi có thể áp dụng, bạn có thể triển khai các hành vi khả năng băm phù hợp cho các lớp tùy chỉnh của riêng mình

Hashable nghĩa là gì trong Python?

Một đối tượng Python có thể băm là bất kỳ đối tượng nào có giá trị băm — một mã định danh số nguyên của đối tượng đó và không bao giờ thay đổi trong suốt thời gian tồn tại của nó. Để kiểm tra xem một đối tượng có thể băm hay không và tìm ra giá trị băm của nó [nếu có thể băm], chúng ta sử dụng hàm hash[] trên đối tượng này. in[băm[3. 14]]Đầu ra. 322818021289917443.

Python có được đặt Hashable không?

dict , list , set vốn dĩ có thể thay đổi và do đó không thể băm được . str , bytes , freezeset và tuple là bất biến và do đó có thể băm.

Kiểu dữ liệu nào trong Python có thể băm được?

Các loại dữ liệu có thể băm. int , float , str , tuple và NoneType . Các kiểu dữ liệu không thể sửa đổi. dict , danh sách và thiết lập.

Tại sao danh sách trong Python không thể băm được?

Vì danh sách có thể thay đổi, trong khi bộ thì không . Ví dụ: khi bạn lưu trữ hàm băm của một giá trị trong một lệnh, nếu đối tượng thay đổi, giá trị băm được lưu trữ sẽ không tìm ra, vì vậy nó sẽ giữ nguyên.

Chủ Đề