Con trăn băm

Nếu tôi có một bộ có nhiều phần tử, hàm băm của nó có được tính từ id của phần tử hoặc nội dung của phần tử không?

Cũng không. Nó được tính toán trên cơ sở giá trị băm của các phần tử này, chứ không phải "nội dung" [giá trị/thuộc tính] cũng như ID của chúng

Những thứ cơ bản. tại sao băm được sử dụng theo cách của họ

Hãy xem đoạn này trong bảng thuật ngữ tài liệu của python

Một cái gì đó có thể băm được hay không, và nó được băm như thế nào, phụ thuộc vào việc triển khai phương thức __hash__[] của nó. Bản thân Python không biết gì về khả năng biến đổi của một đối tượng. Đó là việc triển khai dự kiến ​​​​sẽ cung cấp các cơ chế phù hợp và tránh những cạm bẫy

Băm rất hữu ích trong việc xác định các đối tượng. Ví dụ: nó tăng tốc độ truy xuất dữ liệu từ dict, xác định giá trị tùy ý của khóa bằng một giá trị số duy nhất từ ​​một khoảng hữu hạn - hàm băm của khóa

Một hàm băm sẽ không thay đổi trong suốt thời gian tồn tại của đối tượng. Mặt khác, một đối tượng có thể ánh xạ tới hai giá trị khác nhau trong một dict hoặc được đưa vào một set hai lần, ngay khi giá trị băm của nó thay đổi

Không đủ để so sánh hai đối tượng bằng giá trị băm của chúng. vào cuối ngày, bạn vẫn có thể cần thực hiện kiểm tra đẳng thức, vì có thể xảy ra xung đột giữa các giá trị băm của hai đối tượng khác nhau. Đó là lý do tại sao các đối tượng có thể băm được yêu cầu triển khai __eq__[]

Điều này liên quan đến khả năng biến đổi. nếu một đối tượng có thể băm biến đổi sao cho nó thay đổi các phép so sánh bình đẳng với các đối tượng có thể băm, đặc biệt là đối tượng có cùng hàm băm - nó phá vỡ hợp đồng và có thể dẫn đến sự kỳ lạ tương tự mà hàm băm đột biến sẽ. Các đối tượng có thể băm không nên thay đổi so sánh giữa chúng

Các đối tượng có thể băm bằng nhau phải có cùng hàm băm. Đây là một hợp đồng chung giúp mọi thứ khác trở nên đơn giản hơn - thật tự nhiên khi giả định rằng x == y ngụ ý rằng cả xy ánh xạ tới cùng một giá trị trong một dict

Băm của một tuple

Hãy xem xét ví dụ đầu tiên của bạn. __hash__[]0 tự băm trên cơ sở các phần tử của nó, trong khi phần tử thứ hai của nó, __hash__[]1, hoàn toàn không có hàm băm - phương thức __hash__[]2 không được triển khai cho nó. Và thế là phương thức __hash__[]3 thất bại

Đó là lý do tại sao một __hash__[]0 với một đối tượng __hash__[]1 bên trong nó không thể băm được. Như bạn có thể thấy, do đó, cũng không chính xác khi nói rằng hàm băm __hash__[]0 dựa trên ID của các phần tử của nó

Lưu ý rằng nếu __hash__[]1 có thể băm ở đây và hàm băm dựa trên các phần tử của nó, việc thay đổi chúng sẽ thay đổi hàm băm của __hash__[]0 bên ngoài, phá vỡ hợp đồng

Tại sao lớp tùy chỉnh của tôi không yêu cầu __hash__[]?

Chúng ta hãy xem tài liệu về mô hình dữ liệu python và nó nói gì về chủ đề này

Các lớp do người dùng định nghĩa có các phương thức __eq__[]__hash__[] theo mặc định;

Nói một cách đơn giản, việc triển khai mặc định so sánh danh tính đối tượng, không liên quan gì đến thuộc tính đối tượng. Đó là lý do tại sao bạn có thể thay đổi các giá trị "bên trong" đối tượng của lớp tùy chỉnh mà không thay đổi hàm băm của nó

Đó cũng là lý do tại sao bạn không cần phải xác định __hash__[] cho các lớp của mình - python sẽ làm điều đó cho bạn trong trường hợp này

Về vấn đề này, bạn đúng - việc triển khai hàm băm mặc định [của CPython] cho các lớp tùy chỉnh dựa trên dict7 của một đối tượng [chứ không phải trên các giá trị "bên trong" của nó]. Đây là một chi tiết triển khai và nó khác nhau giữa các phiên bản Python

Trong các phiên bản Python gần đây hơn, mối quan hệ giữa dict8 và dict7 liên quan đến sự ngẫu nhiên hóa. Điều này ngăn chặn một số hình thức tấn công từ chối dịch vụ, trong đó việc tạo xung đột băm tùy ý có thể làm chậm đáng kể các ứng dụng web. Xem PEP-456

Làm thế nào để nó thực sự băm chính nó?

Mặc dù các chi tiết khá phức tạp và có thể liên quan đến một số phép toán cao cấp, nhưng việc triển khai hàm băm cho các đối tượng bộ được viết bằng C và có thể xem tại đây [xem dict0]

Phép tính liên quan đến việc XOR một hằng số với giá trị băm của từng phần tử của bộ dữ liệu. Dòng chịu trách nhiệm băm các phần tử là dòng này

y = PyObject_Hash[*p++];

Vì vậy, để trả lời câu hỏi ban đầu của bạn. nó thực hiện một loạt XOR hokus-pocus với giá trị băm của từng phần tử của nó. Nội dung và thuộc tính của các phần tử này có được xem xét hay không phụ thuộc vào các hàm băm cụ thể của chúng

Bộ dữ liệu bao gồm các chuỗi mục được sắp xếp, giống như danh sách. Sự khác biệt chính giữa các bộ và danh sách là bộ không thể thay đổi [không thay đổi] không giống như danh sách có thể [có thể thay đổi]. Đối với người lập trình mới tiếp cận với python thì list và dict có thể sẽ dễ dàng tiếp cận hơn tuple

Nội dung chính Hiển thị

  • 1. Khởi tạo Tuple
  • 2. Truy cập các giá trị trong Tuples
  • 3. Cắt Tuple
  • 4. Tuples is any variable
  • 5. Phương pháp tuple
  • 6. Ưu điểm của Tuples so với Lists
  • 1. Khởi tạo Tuple
  • 2. Truy cập các giá trị trong Tuples
  • 3. Cắt Tuple
  • 4. Tuples is any variable
  • 5. Phương pháp tuple
  • 6. Ưu điểm của Tuples so với Lists
  • Thảo luận
  • Trong các bài viết trước, Kteam đã giới thiệu cho bạn KExpress DIST LIST, một vùng chứa tuyệt vời trong Python
  • Công dụng. Tương tự phương thức index của chuỗi dữ liệu
  • Cách khởi tạo Tuple
  • Sử dụng cặp dấu ngoặc [] và đặt giá trị bên trong
  • Đó là do khi bạn viết bất kỳ giá trị nào được đặt trong cặp dấu ngoặc đơn thì nó được coi là một giá trị
  • Sử dụng Tuple Comprehension
  • Bạn hãy chú ý khi khởi động tuple với một giá trị
  • Đó là do khi bạn viết bất kỳ giá trị nào được đặt trong cặp dấu ngoặc đơn thì nó được coi là một giá trị
  • Vì sao lại phải coi là một giá trị?
  • Vì khi ta tính toán, hay sử dụng cặp trích [] để được ưu tiên. used in memory of Tuple less than so with ListLuyện tập – Thử thách – Không sợ khó”

Chủ Đề