为什么slice对象在python中是不可散列的

iovurdzv  于 2023-06-28  发布在  Python
关注(0)|答案(3)|浏览(112)

为什么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

这不是什么大事,我只是想知道这背后有什么道理。

q8l4jmvw

q8l4jmvw1#

作为解决方法,您可以使用支持pickle切片对象的__reduce__()方法:

>>> s
slice(2, 10, None)
>>> s1=s.__reduce__()
>>> s1
(<class 'slice'>, (2, 10, None))

虽然 slice 不是hashable,但它的表示是:

>>> hash(s1)
-5954655800066862195
>>> {s1:'pickled slice'}
{(<class 'slice'>, (2, 10, None)): 'pickled slice'}

你可以很容易地从那里重建切片:

>>> slice(*s1[1])
slice(2, 10, None)
thigvfpy

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为{找到相关的(和一些误报)。

4smxwvx5

4smxwvx53#

从Python 3.12(尚未发布最终版本)开始,slice对象是可散列的(假设startstopstep是***可散列的***)。

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

相关问题