Подтвердить что ты не робот

ТипError: Тип расщепления

Я пытаюсь получить список списка кортежей: что-то вроде [ [(1,0),(2,0),(3,0)],[(1,1),(2,1),(3,1)....]] Я использовал это утверждение

set([(a,b)for a in range(3)]for b in range(3))

Но это дает мне ошибку

TypeError: unhashable type: 'list'

У меня есть 2 вопроса для гуру Python:

a) Когда я смотрю на определение Python Hashable -

"Объект hashable, если он имеет значение хэша, которое никогда не изменяется в течение его жизненного цикла (ему нужен метод хеша())

когда я использовал функцию dir над выражением выше

dir([(a,b)for a in range(3)]for b in range(3))

кажется, что есть __hash__. Итак, почему я получаю ошибку?

Мне удалось получить [[(0, 0), (1, 0), (2, 0)], [(0, 1), (1, 1), (2, 1)], [(0, 2), (1, 2), (2, 2)]] используя команду списка:

list(list((a,b) for a in range(3)) for bin range(3))

b) и установите оба параметра Iterable в качестве параметра. Почему один работает (список), а другой не установлен (?)?

4b9b3361

Ответ 1

Вы создаете вызов set через set(...), а set нужны хешируемые элементы. У вас нет списка списков. Потому что list arent hashable.

[[(a,b) for a in range(3)] for b in range(3)] - это список. Это не хешируемый тип. __hash__, который вы видели в каталоге dir (...), не является методом, а просто None.

Пояснение списка возвращает список, вам не нужно явно использовать список там, просто используйте:

>>> [[(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)]]

Попробуйте:

>>> 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'

Ответ 2

TLDR:

- Вы не можете хешировать список, набор или указание поместить его в наборы

- Вы можете хешировать кортеж, чтобы поместить его в набор.

Пример:

>>> {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)])

Обратите внимание, что хеширование является каким-то рекурсивным, и приведенное выше справедливо для вложенных элементов:

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

Клавиши DICT также могут быть хэшируемыми, поэтому вышеизложенное относится и к клавишам DICT.

Ответ 3

Список не сотрясается, потому что его содержимое может меняться в течение всего срока его службы. Вы можете в любой момент обновить элемент, содержащийся в списке.

В списке не используется хэш для индексирования, поэтому он не ограничивается элементами хеширования.

Ответ 4

Причина реальная, потому что set не работает, так это то, что она использует хэш-функцию для различения разных значений. Это означает, что набор разрешает только хешируемые объекты. Почему список не хешируется, уже указано.

Ответ 5

... и поэтому вы должны сделать что-то вроде этого:

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

... и при необходимости конвертировать обратно в список

Ответ 6

Вы обнаружите, что экземпляры list не предоставляют __hash__ -rather, этот атрибут каждого списка фактически None (try print [].__hash__). Таким образом, list не сотрясается.

Причина, по которой ваш код работает с list, а не set, состоит в том, что set создает один набор элементов без дубликатов, тогда как список может содержать произвольные данные.