What does hash do in python?
Question: I saw an example of code that where `hash` function is applied to tuple. As a
result it returns a negative integer. I wonder what does this function does.
Google does not help. I found a page that explains how hash is calculated but
it does not explain why we need this function.


Answer: [A hash is an fixed sized integer that identifies a particular
value](http://en.wikipedia.org/wiki/Hash_function). Each value need to have
it's own hash, so for the same value you will get the same hash even if it's
not the same object.

    
    
    >>> hash("Look at me!")
    4343814758193556824
    >>> f = "Look at me!"
    >>> hash(f)
    4343814758193556824
    

Hash values need to be created in such a way that the resulting values are
evenly distributed to reduce the number of hash collisions you get. Hash
collisions are when two different values have the same hash. Therefore,
relatively small changes often result in very different hashes.

    
    
    >>> hash("Look at me!!")
    6941904779894686356
    

These numbers are very useful, as they enable quick look-up of values in a
large collection of values. Examples of they use is in Python's `set` and
`dict`. In a `list`, if you want to check if a value is in the list, with `if
x in values:`, Python needs to go through the whole list and compare `x` with
each value in the list `values`. This can take a long time for a long `list`.
In a `set`, Python keeps track of each hash, and when you if `if x in
values:`, Python will get the hash-value for `x`, look that up in an internal
structure and then only compare `x` with the values that have the same hash as
`x`.

The same methodology is used for dictionary lookup. This makes lookup in `set`
and `dict` very fast, while lookup in `list` is slow. It also means you can
have non-hashable objects in a `list`, but not in a `set` or as keys in a
`dict`. The typical example of non-hashable objects is any object that is
mutable, ie, you can change it. If you have a mutable object it should not be
hashable, as it's hash then will change over it's life-time, which would cause
a lot of confusion, as an object could end up under the wrong hash value in a
dictionary.

Note that the hash of a value only needs to be the same for one run of Python.
In Python 3.3 they will in fact change for every new run of Python:

    
    
    $ /opt/python33/bin/python3
    Python 3.3.2 (default, Jun 17 2013, 17:49:21) 
    [GCC 4.6.3] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> hash("foo")
    1849024199686380661
    >>> 
    $ /opt/python33/bin/python3
    Python 3.3.2 (default, Jun 17 2013, 17:49:21) 
    [GCC 4.6.3] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> hash("foo")
    -7416743951976404299
    

This is to make is harder to guess what hash value a certain string will have,
which is an important security feature for web applications etc.

Hash values should therefore not be stored permanently. If you need to use
hash values in a permanent way you can take a look at the more "serious" types
of hashes, [cryptographic hash
functions](http://en.wikipedia.org/wiki/Cryptographic_hash_function), that can
be used for making verifiable checksums of files etc.

