ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python使用日期时间片作为dictonary键

2019-08-30 08:57:29  阅读:341  来源: 互联网

标签:python-datetime python dictionary


是否可以使用日期时间片作为字典键?

例:

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有