TypeError : Unhashable type

前端 未结 6 670
灰色年华
灰色年华 2020-11-29 05:45

I am trying to get a list of list of tuples : something like [ [(1,0),(2,0),(3,0)],[(1,1),(2,1),(3,1)....]] I used this statement

set([(a,b)for         


        
相关标签:
6条回答
  • 2020-11-29 06:16

    TLDR:

    - You can't hash a list, a set, nor a dict to put that into sets

    - You can hash a tuple to put it into a set.

    Example:

    >>> {1, 2, [3, 4]}
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'list'
    
    >>> {1, 2, (3, 4)}
    set([1, 2, (3, 4)])
    

    Note that hashing is somehow recursive and the above holds true for nested items:

    >>> {1, 2, 3, (4, [2, 3])}
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'list'
    

    Dict keys also are hashable, so the above holds for dict keys too.

    0 讨论(0)
  • 2020-11-29 06:20

    ... and so you should do something like this:

    set(tuple ((a,b) for a in range(3)) for b in range(3))
    

    ... and if needed convert back to list

    0 讨论(0)
  • 2020-11-29 06:21

    A list is unhashable because its contents can change over its lifetime. You can update an item contained in the list at any time.

    A list doesn't use a hash for indexing, so it isn't restricted to hashable items.

    0 讨论(0)
  • 2020-11-29 06:27

    You are creating a set via set(...) call, and set needs hashable items. You can't have set of lists. Because list's arent hashable.

    [[(a,b) for a in range(3)] for b in range(3)] is a list. It's not a hashable type. The __hash__ you saw in dir(...) isn't a method, it's just None.

    A list comprehension returns a list, you don't need to explicitly use list there, just use:

    >>> [[(a,b) for a in range(3)] for b in range(3)]
    [[(0, 0), (1, 0), (2, 0)], [(0, 1), (1, 1), (2, 1)], [(0, 2), (1, 2), (2, 2)]]
    

    Try those:

    >>> a = {1, 2, 3}
    >>> b= [1, 2, 3]
    >>> type(a)
    <class 'set'>
    >>> type(b)
    <class 'list'>
    >>> {1, 2, []}
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'list'
    >>> print([].__hash__)
    None
    >>> [[],[],[]] #list of lists
    [[], [], []]
    >>> {[], [], []} #set of lists
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'list'
    
    0 讨论(0)
  • 2020-11-29 06:30

    You'll find that instances of list do not provide a __hash__ --rather, that attribute of each list is actually None (try print [].__hash__). Thus, list is unhashable.

    The reason your code works with list and not set is because set constructs a single set of items without duplicates, whereas a list can contain arbitrary data.

    0 讨论(0)
  • 2020-11-29 06:36

    The real reason because set does not work is the fact, that it uses the hash function to distinguish different values. This means that sets only allows hashable objects. Why a list is not hashable is already pointed out.

    0 讨论(0)
提交回复
热议问题