Python使用日期时间片作为dictonary键
作者:互联网
是否可以使用日期时间片作为字典键?
例:
st = datetime.datetime(2010, 12, 31, 0, 0)
en = datetime.datetime(2011, 12, 28, 0, 0)
b = []
b[slice(st,en)] = 'some_random_value_could_be_anything' # Error!
发生以下两个错误之一:
在单个字典案例中:
TypeError: slice indices must be integers or None or have an __index__ method
在嵌套字典中:
TypeError: unhashable type
解决方法:
免责声明:这个答案主要是为了说明Python允许你做的事情(很多).此外,你可能不希望以这种方式做事(事实上,你可以做的事情并不意味着你应该这样做)
这就是说,getitem(self, key)的文档说明:
For sequence types, the accepted keys should be integers and slice
objects.
这意味着任何想要模仿sequence type行为的类(例如列表)都必须准备实现__getitem__,其中key可以是类型slice.那种(有点)解释(或者至少与某种方式有关) )为什么在你的字典中你得到一个TypeError:unhashable类型当你尝试做b [slice(st,en)] =’bla’:这是因为它试图使用slice(st,en)实例作为字典键.切片对象不可清除,因此不能用作dict键. dict类型不是序列类型,因此尝试切片字典没有意义.
假设你有:
{
… ‘foo’: 1,
… ‘bar’: 2,
… ‘baz’: 3,
… }
从’foo’到’bar’的切片是什么意思?你会按照输入的顺序返回一组键吗? (‘foo’,’bar’,’baz’)? Python不知道这一点.它会是__hash__吗?这是内部的,当它如此切片时毫无意义.
所有这些都说,这是一件非常非常糟糕的事情……但那“有效”:
import datetime class DatetimeDict(dict): def __getitem__(self, key): if isinstance(key, slice): sliced = {} start_dt = key.start stop_dt = key.stop step = key.step or 1 internal_keys = sorted(self.keys()) if start_dt is None: start_index = 0 else: start_index = internal_keys.index(start_dt) end_index = internal_keys.index(stop_dt) for i in range(start_index, end_index, step): sliced.update({internal_keys[i]: self[internal_keys[i]]}) return sliced else: return super(DatetimeDict, self).__getitem__(key) def __setitem__(self, key, val): return super(DatetimeDict, self).__setitem__(key, val) a = DatetimeDict() a[datetime.datetime.strptime('2014/01/01', '%Y/%m/%d')] = 'foo', a[datetime.datetime.strptime('2014/01/02', '%Y/%m/%d')] = 'bar', a[datetime.datetime.strptime('2014/01/03', '%Y/%m/%d')] = 'baz', a[datetime.datetime.strptime('2014/01/04', '%Y/%m/%d')] = 'bla', from_dt = datetime.datetime.strptime('2014/01/02', '%Y/%m/%d') to_dt = datetime.datetime.strptime('2014/01/04', '%Y/%m/%d') print a[from_dt:to_dt]
这输出:
{ datetime.datetime(2014, 1, 2, 0, 0): ('bar',), datetime.datetime(2014, 1, 3, 0, 0): ('baz',) }
但是糟糕,糟糕的坏… DatetimeDict变成了一个奇怪的构造,它是一个字典,但同时表现得像一个序列类型……坏.
编辑(重读后,我很确定我误解了这个问题)
你实际上并没有尝试切割字典,你在哪里?在我学会阅读的那一天,我将征服世界……
标签:python-datetime,python,dictionary 来源: https://codeday.me/bug/20190830/1767078.html