为什么python中的切片对象不可清除:
>>> s = slice(0, 10)
>>> hash(s)
TypeError Traceback (most recent call last)
<ipython-input-10-bdf9773a0874> in <module>()
----> 1 hash(s)
TypeError: unhashable type
Run Code Online (Sandbox Code Playgroud)
他们似乎是不可改变的:
>>> s.start = 5
TypeError Traceback (most recent call last)
<ipython-input-11-6710992d7b6d> in <module>()
----> 1 s.start = 5
TypeError: readonly attribute
Run Code Online (Sandbox Code Playgroud)
上下文,我想创建一个将python int或slice对象映射到某些值的字典,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
作为一种解决方法,我需要特殊的案例切片:
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
Run Code Online (Sandbox Code Playgroud)
这不是什么大问题,我只想知道背后是否有一些推理.
补丁#408326旨在分配给d [:]一个错误,其中d是字典.请参阅http://mail.python.org/pipermail/python-list/2001-March/072078.html开始的讨论 .
切片是专门设置为不可用的,所以如果你试图切片分配给一个字典,你会得到一个错误.
不幸的是,邮件列表归档链接看起来不稳定.报价中的链接已经死了,我建议使用的备用链接也已死亡.我能指出的最好的是整个月消息的存档链接; 您可以按Ctrl-F {查找相关的(以及一些误报).
解决方法是,可以使用__reduce__()支持酸洗切片对象的方法:
>>> s
slice(2, 10, None)
>>> s1=s.__reduce__()
>>> s1
(<class 'slice'>, (2, 10, None))
Run Code Online (Sandbox Code Playgroud)
虽然切片不可散列,但其表示为:
>>> hash(s1)
-5954655800066862195
>>> {s1:'pickled slice'}
{(<class 'slice'>, (2, 10, None)): 'pickled slice'}
Run Code Online (Sandbox Code Playgroud)
您可以轻松地从中重构切片:
>>> slice(*s1[1])
slice(2, 10, None)
Run Code Online (Sandbox Code Playgroud)
从Python 3.12(2023 年 10 月 2 日发布)开始,slice对象是可哈希的(前提是start、stop和step是可哈希的)。
>>> s = slice(1, 10, 2)
>>> hash(s)
5929446288262424708
>>> s = slice(1, 10, [])
>>> hash(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
Run Code Online (Sandbox Code Playgroud)