0

我对设置索引有疑问。这是一个例子。

>>> somelist = ['A', 'B', 'C', 'A', 'B']
>>> {x:y for x,y in enumerate(somelist)}

{0: 'A', 1: 'B', 2: 'C', 3: 'A', 4: 'B'}

我真正想要的是这样的:

{{0}: 'A', {1}: 'B', {2}: 'C', {3}: 'A', {4}: 'B'}

我试过{{x}:y for x,y in enumerate(somelist)}了,但它不起作用。

TypeError:不可散列的类型:'set'

感谢任何帮助。谢谢

4

1 回答 1

3

您只能对字典键使用不可变值。set()值是可变的,因此不能使用:

>>> lst = ['A', 'B', 'C', 'A', 'B']
>>> {{x}: y for x, y in enumerate(lst)}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <dictcomp>
TypeError: unhashable type: 'set'

改为使用frozenset()

{frozenset([x]): y for x, y in enumerate(lst)}

演示:

>>> lst = ['A', 'B', 'C', 'A', 'B']
>>> {frozenset([x]): y for x, y in enumerate(lst)}
{frozenset([4]): 'B', frozenset([2]): 'C', frozenset([3]): 'A', frozenset([0]): 'A', frozenset([1]): 'B'}

字典键必须是可散列的;请参阅映射类型文档:

字典的键几乎是任意值。不可散列的值,即包含列表、字典或其他可变类型的值(按值而不是对象标识进行比较)不能用作键。

Python 词汇表中的可散列条目:

一个对象是hashable如果它有一个在其生命周期内永远不会改变的哈希值(它需要一个__hash__()方法),并且可以与其他对象进行比较(它需要一个__eq__()__cmp__()方法)。比较相等的可散列对象必须具有相同的散列值。

因为set值是可变的,所以它们不符合可散列标准;现在比较相等的任何两个集合,以后都可以更改为不再相等,因此它们的哈希值也需要更改。因为字典和集合都依赖于改变的哈希值,所以可变容器不能用作字典键。

字典(与相反)不限于可散列对象。

如果您想创建设置,请使用循环:

dct = {}
for x, y in enumerate(lst):
    dct.setdefault(y, set()).add(x)

或改用collections.defaultdict对象并避免.setdefault()调用:

from collections import defaultdict
dct = defaultdict(set)
for x, y in enumerate(lst):
    dct[y].add(x)

演示:

>>> lst = ['A', 'B', 'C', 'A', 'B']
>>> dct = {}
>>> for x, y in enumerate(lst):
...     dct.setdefault(y, set()).add(x)
... 
>>> dct
{'A': set([0, 3]), 'C': set([2]), 'B': set([1, 4])}
>>> from collections import defaultdict
>>> dct = defaultdict(set)
>>> for x, y in enumerate(lst):
...     dct[y].add(x)
... 
>>> dct
defaultdict(<type 'set'>, {'A': set([0, 3]), 'C': set([2]), 'B': set([1, 4])})
于 2013-07-15T13:59:25.633 回答