Home > Enterprise >  different behaviour of unhashable typeError between cpp and python
different behaviour of unhashable typeError between cpp and python

Time:05-05

It is ok to insert a vector to a set in cpp, which not works in python however. Codes shown below:

// OK in cpp
set<vector<int>> cpp_set;
cpp_set.insert(vector<int>{1,2,3});

// not OK in python
py_set = set()
py_set.add([1,2,3])  # TypeError: unhashable type: 'list'
py_set.add({1,2,3})  # TypeError: unhashable type: 'set'

Even adding a set to a set is not allowed, and I don't understand why a set is unhashable.

Why does the difference happens? And is it a permitted good way to use in cpp? I mean adding a vector to a set.

CodePudding user response:

Python's set is a hash table, and has no hashing functions for set and list.

std::set is not a hash table but a sequence ordered by an ordering relation (std::less by default).
You can use std::set with any type where you can define a strict weak ordering.

Try std::unordered_set in C and you will encounter problems.

CodePudding user response:

Elements of a container modeling a mathematical set should always be immutable, regardless of language, which is important for the guarantees/invariants that are typically associated with such a type. The difference between Python and C here is that Python requires an immutable type up front, while C just uses const to make one immutable.

Notes:

  • The elements of a C set<T> are actually T const.
  • Of course, C has const_cast, so it's not as immutable as it may seem.
  • Storing an element in a set creates a copy. Modifying the original doesn't change the copy.
  • For a C hash set (std::unordered_set), you have the additional requirement that you must be able to hash the elements. The hash of an element must remain the same over time as well, which is why it has similar limitations.
  • Related