Python将某些文本从大字符串放入字典中

时间:2015-04-05 11:04:55

标签: python dictionary

我正在尝试计算标记为On和Off之间的持续时间。

以下是一个字符串中两行的示例:

01/01/2015 7:30:10 a.m. Tag off : 16 Address Ave     $1.00   $26.00
01/01/2015 7:40:17 a.m. Tag on : 127 Address St           $27

目前我将忽略该地址并专注于计算持续时间。每行都有Tag Off信息和Tag On信息,我有大约60行(所以30对),它们都来自一个.txt文件。

从上面的示例中,持续时间为10分7秒。

这是我的代码:

def import_file(filename):
    input_file = open(filename, 'r' )
    file_contents = input_file.read()
    input_file.close()

def strip():
    contents = import_file("data.txt")

def duration_cal():
    pass

那么剥离所有不必要信息并将有关On或Off的时间和日期放入字典或列表的最佳方法是什么? (计算开启和关闭之间的持续时间)

1 个答案:

答案 0 :(得分:1)

到目前为止看起来你还没做过多大的研究,你只打开一个文件,你甚至不按推荐的方式去做,因为你正在创建一个函数来处理python有一种语言的东西结构。

然后,您不会从import_file()返回文件的内容,因此strip()始终会将contents设置为无。实际上,从设计的角度来看,您的功能并不实用。

更好的方法是:

#!/usr/bin/env python3

import os, sys

def print_durations(durations):
    # this is to print nicely the durations
    pass

def calculate_durations(contents):
    # this is where the fun shall be, see implementation below
    pass

def main():
    if len(sys.argv) != 2:
        print("Usage: {} filename".format(sys.argv[0]))
        sys.exit(1)
    if not os.path.isfile(sys.argv[1]):
        print("Error: {} should be an existing file!".format(sys.argv[1]))
        sys.exit(2)
    with open(sys.argv[1], 'r') as f:
        durations = calculate_durations(f.readlines())
        print_durations(durations)

if __name__ == "__main__":
    main()

这是创建以文件名作为第一个参数的脚本的最简单方法。如果您想要更好的CLI工具,可能需要试用docoptargparse

现在让我们进入有趣的部分,即使你显然没有努力实际尝试来实现算法,这是一个足以真正标记你的问题的理由......但仅限于因为它很有趣,以下是我的看法:

为了获得你的行的有趣位,你可以弹出你的python CLI,并拆分你的字符串以获得相关的部分。如果它在各个方面都是一致的,那么你就不需要像疯狂的正则表达式这样的高级内容:

>>> line = '01/01/2015 7:30:10 a.m. Tag off : 16 Address Ave     $1.00   $26.00'
>>> line.split(' : ')
['01/01/2015 7:30:10 a.m. Tag off','16 Address Ave     $1.00   $26.00']
>>> line.split(' : ')[0]
'01/01/2015 7:30:10 a.m. Tag off'
>>> line.split(' : ')[0].split(' Tag ')
['01/01/2015 7:30:10 a.m.','off']
>>> timestr, status = line.split(' : ')[0].split(' Tag ')
>>> print(status)
off
>>> print(timestr)
01/01/2015 7:30:10 a.m.

现在你需要以一种可以计算delta的方式转换时间,但是由于python不理解a.m.作为am / pm标记,你需要先转换它:

>>> timestr = timestr.replace('a.m.', 'AM')
>>> import datetime
>>> timestamp = datetime.datetime.strptime(timestr, "%d/%m/%Y %I:%M:%S %p")
>>> timestamp
datetime.datetime(2015, 1, 1, 7, 30, 10)

最后得到两个时间戳之间的差值,你只需要减去日期:

>>> timestamp2 = datetime.datetime.strptime(line.split(' : ')[0].split(' Tag ')[0].replace('a.m.', 'AM'), "%d/%m/%Y %I:%M:%S %p")
>>> timestamp2 - timestamp
datetime.timedelta(0, 607)
>>> print(timestamp2 - timestamp)
0:10:07

然后你去!这个函数的内容相同:

import datetime

def calculate_durations(contents):
    last_stamp = None
    durations = []
    for line in contents:
        # extract time and status from the line
        timestr, status = line.split(' : ')[0].split(' Tag ')
        # fix a.m./p.m. to be AM/PM
        timestr = timestr.replace('a.m.', 'AM').replace('p.m.', 'PM')
        # load the time as a python timestamp
        timestamp = datetime.datetime.strptime(timestr, "%d/%m/%Y %I:%M:%S %p")
        # if this is the first timestamp, store the status, and consider the timestamp to be zero
        if last_stamp is None:
            durations.append((datetime.timedelta(0), status))
        # otherwise calculate the timestamp since last
        else:
            durations.append((timestamp-last_stamp, status))
        # save timestamp for next line
        last_stamp = timestamp
    return durations

def print_durations(durations):
    for stamp, status in durations:
        print("{} for {}".format(status, stamp))

你可以复制它,在python命令行中测试它,它将输出:

>>> contents = [
... '01/01/2015 7:30:10 a.m. Tag off : 16 Address Ave     $1.00   $26.00',
... '01/01/2015 7:40:17 a.m. Tag on : 127 Address St           $27']
...
>>> print_durations(calculate_durations(contents))
off for 0:00:00
on for 0:10:07

或者将它作为脚本运行,如果你把它们放在一起:

% python3 myscript.py myfile.log
off for 0:00:00
on for 0:10:07

HTH