Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding the behavior of Python's set

Tags:

python

set

The documentation for the built-in type set says:

class set([iterable])

Return a new set or frozenset object whose elements are taken from iterable. The elements of a set must be hashable.

That is all right but why does this work:

>>> l = range(10)
>>> s = set(l)
>>> s
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

And this doesn't:

 >>> s.add([10])

    Traceback (most recent call last):
      File "<pyshell#7>", line 1, in <module>
        s.add([10])
    TypeError: unhashable type: 'list'

Both are lists. Is some magic happening during the initialization?

like image 236
user225312 Avatar asked Feb 16 '11 21:02

user225312


People also ask

How does the set method work in Python?

set() method is used to convert any of the iterable to sequence of iterable elements with distinct elements, commonly called Set. Parameters : Any iterable sequence like list, tuple or dictionary. Returns : An empty set if no element is passed. Non-repeating element iterable modified as passed as argument.

How do you find the elements of a set in Python?

You cannot access items in a set by referring to an index or a key. But you can loop through the set items using a for loop, or ask if a specified value is present in a set, by using the in keyword.

How do you do set operations in Python?

The most common way of creating a set in Python is by using the built-in set() function. The set() function takes in an iterable and yields a list of objects which will be inserted into the set. The {} syntax places the objects themselves into the set.


4 Answers

When you initialize a set, you provide a list of values that must each be hashable.

s = set()
s.add([10])

is the same as

s = set([[10]])

which throws the same error that you're seeing right now.

like image 189
phihag Avatar answered Oct 23 '22 21:10

phihag


Think of the constructor being something like:

class Set:
    def __init__(self,l):
        for elem in l:
            self.add(elem)

Nothing too interesting to be concerned about why it takes lists but on the other hand add(element) does not.

like image 26
Utku Zihnioglu Avatar answered Oct 23 '22 21:10

Utku Zihnioglu


In [13]: (2).__hash__
Out[13]: <method-wrapper '__hash__' of int object at 0x9f61d84>

In [14]: ([2]).__hash__ # nothing.

The thing is that set needs its items to be hashable, i.e. implement the __hash__ magic method (this is used for ordering in the tree as far as I know). list does not implement that magic method, hence it cannot be added in a set.

like image 25
Gabi Purcaru Avatar answered Oct 23 '22 21:10

Gabi Purcaru


In this line:

s.add([10])

You are trying to add a list to the set, rather than the elements of the list. If you want ot add the elements of the list, use the update method.

like image 37
novalis Avatar answered Oct 23 '22 22:10

novalis