为什么python中的slice对象不是hashable:
>>> s = slice(0, 10)
>>> hash(s)
TypeError Traceback (most recent call last)
<ipython-input-10-bdf9773a0874> in <module>()
----> 1 hash(s)
TypeError: unhashable type
它们似乎是不可改变的:
>>> s.start = 5
TypeError Traceback (most recent call last)
<ipython-input-11-6710992d7b6d> in <module>()
----> 1 s.start = 5
TypeError: readonly attribute
在上下文中,我想创建一个字典,将python int或slice对象Map到一些值,类似于:
class Foo:
def __init__(self):
self.cache = {}
def __getitem__(self, idx):
if idx in self.cache:
return self.cache[idx]
else:
r = random.random()
self.cache[idx] = r
return r
作为一种变通方法,我需要特殊情况切片:
class Foo:
def __init__(self):
self.cache = {}
def __getitem__(self, idx):
if isinstance(idx, slice):
idx = ("slice", idx.start, idx.stop, idx.step)
if idx in self.cache:
return self.cache[idx]
else:
r = random.random()
self.cache[idx] = r
return r
这不是什么大事,我只是想知道这背后有什么道理。
3条答案
按热度按时间q8l4jmvw1#
作为解决方法,您可以使用支持pickle切片对象的
__reduce__()
方法:虽然 slice 不是hashable,但它的表示是:
你可以很容易地从那里重建切片:
thigvfpy2#
关于Python bug tracker:
补丁# 408326被设计为在d是字典的情况下,将错误赋值给d[:]。请参阅从http://mail.python.org/pipermail/python-list/2001-March/072078.html开始的讨论。
切片被特别地设置为不可散列的,所以如果你试图将切片分配给一个dict,你会得到一个错误。
不幸的是,邮件列表存档链接似乎不稳定。引用中的链接死了,alternate link I suggested using也死了。我能给你指出的最好的是that entire month of messages的存档链接;您可以Ctrl-F为
{
找到相关的(和一些误报)。4smxwvx53#
从Python 3.12(尚未发布最终版本)开始,
slice
对象是可散列的(假设start
,stop
和step
是***可散列的***)。