gpt4 book ai didi

python - 如何在 python OrderedDict 上使用字符串键而不是整数进行切片?

转载 作者:IT老高 更新时间:2023-10-28 20:39:00 24 4
gpt4 key购买 nike

由于 OrderedDict 具有列表(带有有序元素)和字典(带有键而不是索引)的特性,因此您可以使用键进行切片似乎很自然。

>>> from collections import OrderedDict
>>> cities = OrderedDict((('san francisco', 650), ('new york', 212), ('shanghai', 8621), ('barcelona', 42423)))
>>> test['shanghai':] # I want all the cities from shanghai to the end of the list
TypeError: unhashable type

有趣的是,这不是由于 OrderedDictionary.__getslice__ 未实现而导致的错误。我尝试将自己的 __getslice__ 方法添加到 OrderedDict,但我一直遇到这个 TypeError 问题。似乎 Python 正在执行某种类型检查以强制切片键只是整数,甚至在它们被传递给 __getslice__ 函数之前,多么不合 Python!

>>> class BetterOrderedDict(OrderedDict):
def __getslice__(self, start=None, end=None, step=1):
return 'potato'

>>> test = BetterOrderedDict((('one', 1), ('two', 2), ('three', 3), ('four', 4)))
>>> print test[1:4]
'potato' # ok this makes sense so far

>>> test['one':'four']
TypeError: unhashable type # WTF, strings are hashable!

所以我的问题是,为什么我不能实现非 int 切片,什么样的类型检查会阻止切片键到达我的 __getslice__ 函数,我可以通过在 C 中使用绑定(bind)实现我的 BetterOrderedDict

最佳答案

__getslice__ 是不推荐使用的实现切片的方式。相反,您应该使用 __getitem__ 处理 slice 对象:

from collections import OrderedDict

class SlicableDict(OrderedDict):
def __getitem__(self, key):
if isinstance(key, slice):
return 'potato({},{},{})'.format(key.start, key.stop, key.step)
return super(SlicableDict, self).__getitem__(key)

>>> s = SlicableDict(a=1, b=2, c=3)
>>> s
SlicableDict([('a', 1), ('c', 3), ('b', 2)])
>>> s['a']
1
>>> s['a':'c']
'potato(a,c,None)'

如果您需要的不仅仅是土 bean ,您可以通过以下方式实现所有三个切片操作:

def _key_slice_to_index_slice(items, key_slice):
try:
if key_slice.start is None:
start = None
else:
start = next(idx for idx, (key, value) in enumerate(items)
if key == key_slice.start)
if key_slice.stop is None:
stop = None
else:
stop = next(idx for idx, (key, value) in enumerate(items)
if key == key_slice.stop)
except StopIteration:
raise KeyError
return slice(start, stop, key_slice.step)

class SlicableDict(OrderedDict):
def __getitem__(self, key):
if isinstance(key, slice):
items = self.items()
index_slice = _key_slice_to_index_slice(items, key)
return SlicableDict(items[index_slice])
return super(SlicableDict, self).__getitem__(key)

def __setitem__(self, key, value):
if isinstance(key, slice):
items = self.items()
index_slice = _key_slice_to_index_slice(items, key)
items[index_slice] = value.items()
self.clear()
self.update(items)
return
return super(SlicableDict, self).__setitem__(key, value)

def __delitem__(self, key):
if isinstance(key, slice):
items = self.items()
index_slice = _key_slice_to_index_slice(items, key)
del items[index_slice]
self.clear()
self.update(items)
return
return super(SlicableDict, self).__delitem__(key)

关于python - 如何在 python OrderedDict 上使用字符串键而不是整数进行切片?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27912308/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com