【问题标题】:set the index in a dictionary Python在字典 Python 中设置索引
【发布时间】:2013-07-15 13:57:42
【问题描述】:

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

>>> 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: unhashable type: 'set'

感谢任何帮助。谢谢

【问题讨论】:

  • 当您声明某些东西不起作用时,包含错误消息。在这种情况下,我很容易猜到哪里出了问题,但你不能指望每个人都这样猜测。
  • 您不想在代码中使用像list 这样的名称;它掩盖了内置类型。改用lstsomelist 或其他任何东西。

标签: python dictionary indexing set


【解决方案1】:

您只能对字典键使用 不可变 值。 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() values

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

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

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

还有hashable entry in the Python glossary

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

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

字典values(相对于keys)不限于可散列对象。

如果您想创建集合 ,请使用循环:

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

【讨论】:

  • 但是为什么 {x:{y} for x,y in enumerate(list)} 会产生 {0: {'A'}, 1: {'B'}, 2: {'C '}, 3: {'A'}, 4: {'B'}} ?
  • @afternoon:那是因为限制只适用于键。
  • mapping types documentation; 字典的键几乎是任意值。不可散列的值,即包含列表、字典或其他可变类型的值(通过值而不是对象标识进行比较)不能用作键。
  • 那么我更喜欢这样的东西,如果它可以工作 {y:{x} for x,y in enumerate(list)}。使用后如何消除“冰冻”?此外, ([4]) 不是我真正想要的 {4}。
  • @afternoon: {4} 是一种新的文字符号,其结果为set([4])frozenset([4]) 是一样的,虽然不是可变的。不要在此处将集合的表示与列表混淆。
猜你喜欢
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
  • 2021-02-27
  • 1970-01-01
  • 2013-07-21
  • 2017-10-02
  • 1970-01-01
相关资源
最近更新 更多