编程语言
首页 > 编程语言> > Python使用日期时间片作为dictonary键

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