用Python创建一个由列表索引的字典

14
我希望创建一个可以通过列表索引的字典。例如,我的字典应该如下所示:
D = {[1,2,3]:1, [2,3]:3}

有人知道怎么做吗?如果我只是输入 D([1,2,3]) = 1,它就会返回错误。


10
不可能的,字典键需要是不可变的。请使用元组代替。 - SilentGhost
那我该怎么做呢?D((1,2,3))=1也会返回一个错误。 - Chris
看起来你使用了 (...),但你应该使用 [...]D[1, 2, 3] = 1 应该可以正常工作。 - Mike Graham
参见:https://dev59.com/oEnSa4cB1Zd3GeqPSfA4 - outis
3个回答

20

字典的键必须是可散列的,而列表不是因为它们是可变的。你可以在创建后更改列表。试想一下,当用作键的数据发生更改时,尝试保持字典会有多么棘手;这没有任何意义。想象一下以下情景:

>>> foo = [1, 2]
>>> bar = {foo: 3}
>>> foo.append(4)

你将会了解到为什么Python不支持将列表用作键。

最明显的解决方案是使用元组而不是列表作为键。

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

1
尝试保持字典有效 - user319799
只需记住:当哈希时,Python不知道(1,2)和(2,1)之间的区别...我不得不创建一个可以做到这一点的类:https://gist.github.com/rjurney/d7913221dd38bee9708716f50c3c002e - rjurney
@rjurney 我觉得你有点困惑。你说的“Python在哈希时不知道(1,2)和(2,1)之间的区别”是什么意思?(顺便说一句,你的类声称可以处理集合,但实际上对于集合来说并不合理。) - Mike Graham
@rjurney - 当我在2.7.6和3.4上运行d = {(1, 2): 3}; print(d[(2, 1)])时,我遇到了一个关键错误。你应该再检查一下。 - rohithpr
@MikeGraham 感谢您提供这些不错的示例。 - simhumileco
显示剩余3条评论

2

字典的键只能是可哈希对象。 如果你想把列表作为键,可以将其转换为元组。

>>>d={}
>>>a = tuple((1,2))
>>>a
(1, 2)
>>>d[a] = 3
>>>print d
{(1, 2): 3}

3
键必须是可哈希的,但不一定是不可变的。您可以拥有可哈希的可变值(虽然这很少有用),也可以拥有不可哈希的不可变值(例如包含不可哈希值的元组)。 - Thomas Wouters
谢谢您的评论,虽然这是同样的事情...您能给一个可变和可哈希的例子吗? - joaquin
4
要使一个对象可被正常哈希,当你对其进行哈希并执行相等比较时,其给出的答案不应发生变化。实际对象可能会以其他方式发生更改。例如,如果我有一个定义人的类“Person”,我可以使用身份比较来确定两个“Person”对象是否相等,而不管我更改了“Person”的年龄或地址等信息。如果可变性不影响相等和哈希计算,则可哈希对象不受影响。 - Mike Graham
@Mike,感谢您的回答,我刚刚将同样的问题作为新的SO问题写了出来。 - joaquin

1
d = {repr([1,2,3]): 'value'}

{'[1, 2, 3]': 'value'}

如其他人所解释的(也可在此处查看),您不能直接使用列表。 但是,如果您确实想使用列表,则可以改用其字符串表示形式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接