Difference between hash() and id()

2024/11/19 9:24:20

I have two user-defined objects, say a and b.
Both these objects have the same hash values.
However, the id(a) and id(b) are unequal.

Moreover,

>>> a is b
False
>>> a == b
True

From this observation, can I infer the following?

  • Unequal objects may have the same hash values.
  • Equal objects need to have the same id values.
  • Whenever obj1 is obj2 is called, the id values of both objects is compared, not their hash values.
Answer

There are three concepts to grasp when trying to understand id, hash and the == and is operators: identity, value and hash value. Not all objects have all three.

  1. All objects have an identity, though even this can be a little slippery in some cases. The id function returns a number corresponding to an object's identity (in cpython, it returns the memory address of the object, but other interpreters may return something else). If two objects (that exist at the same time) have the same identity, they're actually two references to the same object. The is operator compares items by identity, a is b is equivalent to id(a) == id(b).

    Identity can get a little confusing when you deal with objects that are cached somewhere in their implementation. For instance, the objects for small integers and strings in cpython are not remade each time they're used. Instead, existing objects are returned any time they're needed. You should not rely on this in your code though, because it's an implementation detail of cpython (other interpreters may do it differently or not at all).

  2. All objects also have a value, though this is a bit more complicated. Some objects do not have a meaningful value other than their identity (so value an identity may be synonymous, in some cases). Value can be defined as what the == operator compares, so any time a == b, you can say that a and b have the same value. Container objects (like lists) have a value that is defined by their contents, while some other kinds of objects will have values based on their attributes. Objects of different types can sometimes have the same values, as with numbers: 0 == 0.0 == 0j == decimal.Decimal("0") == fractions.Fraction(0) == False (yep, bools are numbers in Python, for historic reasons).

    If a class doesn't define an __eq__ method (to implement the == operator), it will inherit the default version from object and its instances will be compared solely by their identities. This is appropriate when otherwise identical instances may have important semantic differences. For instance, two different sockets connected to the same port of the same host need to be treated differently if one is fetching an HTML webpage and the other is getting an image linked from that page, so they don't have the same value.

  3. In addition to a value, some objects have a hash value, which means they can be used as dictionary keys (and stored in sets). The function hash(a) returns the object a's hash value, a number based on the object's value. The hash of an object must remain the same for the lifetime of the object, so it only makes sense for an object to be hashable if its value is immutable (either because it's based on the object's identity, or because it's based on contents of the object that are themselves immutable).

    Multiple different objects may have the same hash value, though well designed hash functions will avoid this as much as possible. Storing objects with the same hash in a dictionary is much less efficient than storing objects with distinct hashes (each hash collision requires more work). Objects are hashable by default (since their default value is their identity, which is immutable). If you write an __eq__ method in a custom class, Python will disable this default hash implementation, since your __eq__ function will define a new meaning of value for its instances. You'll need to write a __hash__ method as well, if you want your class to still be hashable. If you inherit from a hashable class but don't want to be hashable yourself, you can set __hash__ = None in the class body.

https://en.xdnf.cn/q/26458.html

Related Q&A

get class name for empty queryset in django

I have empty queryset of model Studentstudents = Students.objects.all()If the above queryset is empty, then how can i get the model(class name)?How can i get the model name for empty queryset?EDIT:Ho…

`Sudo pip install matplotlib` fails to find freetype headers. [OS X Mavericks / 10.9] [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.This question does not appear to be about a specific programming problem, a software algorithm, or s…

Parallel processing from a command queue on Linux (bash, python, ruby... whatever)

I have a list/queue of 200 commands that I need to run in a shell on a Linux server. I only want to have a maximum of 10 processes running (from the queue) at once. Some processes will take a few secon…

How do I select and store columns greater than a number in pandas? [duplicate]

This question already has answers here:How do I select rows from a DataFrame based on column values?(17 answers)Closed 28 days ago.I have a pandas DataFrame with a column of integers. I want the rows …

Plotting transparent histogram with non transparent edge

I am plotting a histogram, and I have three datasets which I want to plot together, each one with different colours and linetype (dashed, dotted, etc). I am also giving some transparency, in order to s…

Cross-platform desktop notifier in Python

I am looking for Growl-like, Windows balloon-tip-like notifications library in Python. Imagine writing code like:>>> import desktopnotifier as dn >>> dn.notify(Title, Long description…

set object is not JSON serializable [duplicate]

This question already has answers here:How to JSON serialize sets? [duplicate](12 answers)Closed 9 years ago.When I try to run the following code:import jsond = {testing: {1, 2, 3}} json_string = json…

Python Sqlite3: INSERT INTO table VALUE(dictionary goes here)

I would like to use a dictionary to insert values into a table, how would I do this? import sqlite3db = sqlite3.connect(local.db) cur = db.cursor()cur.execute(DROP TABLE IF EXISTS Media)cur.execute(CR…

Count the uppercase letters in a string with Python

I am trying to figure out how I can count the uppercase letters in a string. I have only been able to count lowercase letters:def n_lower_chars(string):return sum(map(str.islower, string))Example of w…

Multithreading for Python Django

Some functions should run asynchronously on the web server. Sending emails or data post-processing are typical use cases.What is the best (or most pythonic) way write a decorator function to run a func…