从单个列表创建字典词典-Python3

时间:2019-01-16 22:00:30

标签: python python-3.x dictionary

Linux上的Python 3.6.5 / 3.7.1

努力创建以字典作为值的字典。

我想根据列表中的日期和时间数据创建字典(最终创建带有bokeh的图表)。

必须先问过这个问题,但是我找不到一组搜索结果来返回对我来说很重要的结果。

nb我本质上是一名业余编码员,而且我不容易像真正的程序员一样从算法上思考。

数据在列表中(最多3200个项目): 每一项都是一个小时的时钟周期内某个日期发生事件的记录。

因此; ['03/01/19 09:00', '03/01/19 09:00', '03/01/19 09:00',]表示在03/01/2019的0900-1000之间发生了3个事件。

仅记录带有事件的时钟周期,因此,如果没有事件,则没有时间戳。

nb日期格式为ddmmyy

示例数据:

dtl = [
    '06/01/19 12:00', '06/01/19 12:00', '06/01/19 11:00', '05/01/19 21:00',
    '05/01/19 17:00', '05/01/19 17:00', '05/01/19 14:00', '03/01/19 21:00',
    '03/01/19 17:00', '03/01/19 12:00', '03/01/19 12:00', '03/01/19 12:00',
    '03/01/19 12:00', '03/01/19 12:00', '03/01/19 11:00', '03/01/19 10:00',
    '03/01/19 10:00', '03/01/19 09:00','03/01/19 09:00','03/01/19 09:00',
]

所需的字典如下:

dtd = {
    '03/01/19': {
         '00': 0, '01': 0, '02': 0, '03': 0, '04': 0, '05': 0,
         '06': 0, '07': 0, '08': 0, '09': 3, '10': 2, '11': 1,
         '12': 5, '13': 0, '14': 0, '15': 0, '16': 0, '17': 1,
         '18': 0, '19': 0, '20': 0, '21': 1, '22': 0, '23': 0,
     },
     '04/01/19': {
         '00': 0, ... '23': 0
     },
     '05/01/19': {
         '00': 0, ... 
     } ... etc
}

很明显,我至少可以用键来初始化字典:

{i.split()[0]:{} for i in dtl}

但是后来我无法确定要更新带有计数的下标所需要做的事情,因此也找不到从原始列表到所需字典的方法。我要转一圈!

3 个答案:

答案 0 :(得分:2)

一旦按日期拆分成字典,就可以将Counterdefaultdict结合起来,从而非常有效地完成此操作。因此,首先按日期划分:

from collections import Counter, defaultdict

dtd = defaultdict(list)
for date, time in (item.split() for item in dtl):
    dtd[date].append(time[:2])

现在,您可以轻松地计算现有项目,并使用它们来初始化defaultdict,它将为缺少的时间返回零:

for key in dtd:
    dtd[key] = defaultdict(int, Counter(dtd[key]))

结果是:

defaultdict(list, {
    '03/01/19': defaultdict(int, {
        '09': 3,
        '10': 2,
        '11': 1,
        '12': 5,
        '17': 1,
        '21': 1
    }),
    '05/01/19': defaultdict(int, {'14': 1, '17': 2, '21': 1}),
    '06/01/19': defaultdict(int, {'11': 1, '12': 2})
})

由于此处的对象是defaultdict,因此您将能够查询原始数据集中没有的日期和时间。您可以通过将结果转换为仅包含所需键的常规dict来避免这种情况:

hours = ['%02d' % h for h in range(24)]
dtd = {date: {h: d[h] for h in hours} for date, d in dtd}

答案 1 :(得分:2)

我建议您使用collections.defaultdict,因为您的某些计数可以为0。

这是一个选择:

from collections import defaultdict

dtl = ['06/01/19 12:00', '06/01/19 12:00', '06/01/19 11:00', 
       '05/01/19 21:00', '05/01/19 17:00', '05/01/19 17:00', 
       '05/01/19 14:00', '03/01/19 21:00', '03/01/19 17:00',
       '03/01/19 12:00', '03/01/19 12:00', '03/01/19 12:00', 
       '03/01/19 12:00', '03/01/19 12:00', '03/01/19 11:00', 
       '03/01/19 10:00', '03/01/19 10:00', '03/01/19 09:00',
       '03/01/19 09:00','03/01/19 09:00',]

# Nested defaultdict
result = defaultdict(lambda: defaultdict(int))

for date_time in dtl:
    date, time = date_time.split()
    result[date][time.split(':')[0]] += 1

输出(使用pprint):

defaultdict(<function <lambda> at 0x7f20d5c37c80>,
            {'03/01/19': defaultdict(<class 'int'>,
                                     {'09': 3,
                                      '10': 2,
                                      '11': 1,
                                      '12': 5,
                                      '17': 1,
                                      '21': 1}),
             '05/01/19': defaultdict(<class 'int'>,
                                     {'14': 1,
                                      '17': 2,
                                      '21': 1}),
             '06/01/19': defaultdict(<class 'int'>, {'12': 2, '11': 1})})

如果您真的想显示0进行打印,那么我真的没有办法像我在此处那样保留times数组并初始化dict那样。

times = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10',
         '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21',
         '22', '23']

dtl = ['06/01/19 12:00', '06/01/19 12:00', '06/01/19 11:00', 
       '05/01/19 21:00', '05/01/19 17:00', '05/01/19 17:00', 
       '05/01/19 14:00', '03/01/19 21:00', '03/01/19 17:00',
       '03/01/19 12:00', '03/01/19 12:00', '03/01/19 12:00', 
       '03/01/19 12:00', '03/01/19 12:00', '03/01/19 11:00', 
       '03/01/19 10:00', '03/01/19 10:00', '03/01/19 09:00',
       '03/01/19 09:00','03/01/19 09:00']

result = {date_time.split()[0] : {time : 0 for time in times} for date_time in dtl}

for date_time in dtl:
    date, time = date_time.split()
    result[date][time.split(':')[0]] += 1

以下输出:

{'06/01/19': {'00': 0, '01': 0, '02': 0, '03': 0, '04': 0, '05': 0, '06': 0, '07': 0, '08': 0, '09': 0, '10': 0, '11': 1, '12': 2, '13': 0, '14': 0, '15': 0, '16': 0, '17': 0, '18': 0, '19': 0, '20': 0, '21': 0, '22': 0, '23': 0}, '05/01/19': {'00': 0, '01': 0, '02': 0, '03': 0, '04': 0, '05': 0, '06': 0, '07': 0, '08': 0, '09': 0, '10': 0, '11': 0, '12': 0, '13': 0, '14': 1, '15': 0, '16': 0, '17': 2, '18': 0, '19': 0, '20': 0, '21': 1, '22': 0, '23': 0}, '03/01/19': {'00': 0, '01': 0, '02': 0, '03': 0, '04': 0, '05': 0, '06': 0, '07': 0, '08': 0, '09': 3, '10': 2, '11': 1, '12': 5, '13': 0, '14': 0, '15': 0, '16': 0, '17': 1, '18': 0, '19': 0, '20': 0, '21': 1, '22': 0, '23': 0}}

答案 2 :(得分:0)

一种快速而肮脏的方式是

#!/usr/bin/env python3

def convert(dt):
    ret = {}
    for elem in dt:
        d,t = elem.split()
        t = t.split(":")[0]
        # not a valid value
        if not d: pass

        # we inserted d already
        if d in ret:
            if t in ret[d]:
                ret[d][t] += 1
        else:
            ret[d] = {'00': 0, '01': 0, '02': 0, '03': 0, '04': 0, '05': 0,
                    '06': 0, '07': 0, '08': 0, '09': 0, '10': 0, '11': 0, 
                    '12': 0, '13': 0, '14': 0, '15': 0, '16': 0, '17': 0, 
                    '18': 0, '19': 0, '20': 0, '21': 0, '22': 0, '23': 0 }
    return ret

dtl = ['06/01/19 12:00', '06/01/19 12:00', '06/01/19 11:00', '05/01/19 21:00', '05/01/19 17:00', '05/01/19 17:00', '05/01/19 14:00', '03/01/19 21:00', '03/01/19 17:00','03/01/19 12:00', '03/01/19 12:00', '03/01/19 12:00', '03/01/19 12:00', '03/01/19 12:00', '03/01/19 11:00', '03/01/19 10:00', '03/01/19 10:00', '03/01/19 09:00','03/01/19 09:00','03/01/19 09:00']

print(convert(dtl))