'different behaviour of unhashable typeError between cpp and python
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.
Solution 1:[1]
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.
Solution 2:[2]
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 actuallyT const. - Of course, C++ has
const_cast, so it's not as immutable as it may seem. - Storing an element in a
setcreates 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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | molbdnilo |
| Solution 2 | Ulrich Eckhardt |
