Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python读取和比较文件中的行_Python_File_Compare - Fatal编程技术网

使用Python读取和比较文件中的行

使用Python读取和比较文件中的行,python,file,compare,Python,File,Compare,我有一个以下格式的文件 15/07/2010 14:14:13 changed_status_from_Offline_to_Available 15/07/2010 15:01:09 changed_status_from_Available_to_Offline 15/07/2010 15:15:35 changed_status_from_Offline_to_Away became_idle 15/07/2010 15:16:29 changed_status_from_Away_to_

我有一个以下格式的文件

15/07/2010 14:14:13 changed_status_from_Offline_to_Available
15/07/2010 15:01:09 changed_status_from_Available_to_Offline
15/07/2010 15:15:35 changed_status_from_Offline_to_Away became_idle
15/07/2010 15:16:29 changed_status_from_Away_to_Available became_unidle
15/07/2010 15:45:40 changed_status_from_Available_to_Away became_idle
15/07/2010 16:05:40 changed_status_from_Away_to_Available became_unidle
15/07/2010 16:51:39 changed_status_from_Available_to_Offline
20/07/2010 13:07:26 changed_status_from_Offline_to_Available
我需要在python中创建一个函数,该函数必须包含以下参数:日期和时间。如果日期匹配且时间小于函数调用中的时间,则应读取文件并返回第二个状态。就是

假设我调用函数returnstatus(15/07/2010,15:10:01)。 该函数应转到该文件,并返回用户当时的状态,在本例中为“脱机”


我是一个Python新手,任何帮助都将不胜感激

我建议您阅读python文档,特别是函数strtime,它可以将时间的文本表示形式解析为编程表示形式

调用
returnstatus
您在问题中编写的方式肯定会失败,您可能希望使用时间的字符串表示形式(即“15/07/2010 15:10:01”)或通过传递时间模块中定义的数据类型之一来调用它

编辑:显然,如果传入字符串时间,则在文件中查找它会容易得多:

if substring in line:
 # do stuff
这有意义吗,或者你想让我解释一下吗

编辑 你说的是真的吗

日期匹配且时间小于函数调用中的时间

换句话说,如果调用
return\u status(2010年7月16日)
,会发生什么?你应该“离线”吗

另一次编辑
我对它进行了编辑,以便进行合理的
datetime
比较。我认为您阅读不平等性的方式是错误的:我们循环文件中的行,直到我们希望获取的日期后的第一行(在
statDate>lineDate
期间继续阅读)。一旦该测试失败,
line
是所需日期后的第一行,因此其
from
值是我们请求时的状态。您应该使用
datetime.datetime

调用函数,正如Yoni所说,传递字符串参数(如果有)可能会更好。您还可以在中找到有用的类型。您还需要查看该函数。

尝试以下操作:

import datetime

filein = open("filein", "r")

class Status:   
    def __init__(self, date, time, status):
        print date.split('/')
        day, month, year = map(int, date.split('/'))
        hour, minute, second = map(int, time.split(':'))
        self.date_and_time = datetime.datetime(year=year, month=month, day=day, hour=hour, minute=minute, second=second)
        self.status = status

list = []
line = filein.readline().rstrip('\n')

while line != "":
    print line
    date, time, status = line.split(' ')[:3]
    status = status.split('_')
    status.reverse()
    status = status[0]
    status_it = Status(date=date, time=time, status=status)
    line = filein.readline().rstrip('\n')
    list.append(status_it)

def query (date, time):
    day, month, year = map(int, date.split('/'))
    hour, minute, second = map(int, time.split(':'))
    date_and_time = datetime.datetime(year=year, month=month, day=day, hour=hour, minute=minute, second=second)

    for counter, it in enumerate(list):
        if date_and_time >= it.date_and_time and (date_and_time < list[counter + 1].date_and_time or counter == len(list) - 1):
            print it.status
            return
    print "I don't know the status"

query("15/07/2010", "15:10:01")
导入日期时间
filein=打开(“filein”、“r”)
班级状况:
定义初始(自我、日期、时间、状态):
打印日期。拆分(“/”)
日、月、年=映射(int,date.split('/'))
小时,分钟,秒=映射(int,time.split(':'))
self.date_和_time=datetime.datetime(年=年,月=月,日=日,小时=小时,分钟=分钟,秒=秒)
self.status=状态
列表=[]
line=filein.readline().rstrip('\n')
在线时!="":
打印行
日期、时间、状态=行分割(“”)[:3]
状态=状态。拆分(“”)
状态。反向()
状态=状态[0]
状态=状态(日期=日期,时间=时间,状态=状态)
line=filein.readline().rstrip('\n')
列表。追加(状态_it)
def查询(日期、时间):
日、月、年=映射(int,date.split('/'))
小时,分钟,秒=映射(int,time.split(':'))
日期和时间=日期时间。日期时间(年=年,月=月,日=日,小时=小时,分钟=分钟,秒=秒)
对于计数器,它位于枚举(列表)中:
如果日期和时间>=it.date和时间和(日期和时间<列表[计数器+1]。日期和时间或计数器==len(列表)-1):
打印它。状态
回来
打印“我不知道状态”
查询(“15/07/2010”,“15:10:01”)
问题中的大多数人可能希望将参数作为
字符串传递,并且希望使用单个函数

假设我调用函数returnstatus(15/07/2010,15:10:01)。该函数应转到该文件,并返回用户当时的状态,在本例中为“脱机”


基本上,您需要做的是从日志中提取日期和时间,并将其转换为易于比较的格式。输入
datetime

import datetime

def getStatus(log_list, dt, tm):
 #filter the list
 log_list = [a_log_entry for a_log_entry in log_list if a_log_entry[0] == dt and a_log_entry[1] <= tm]

    #sort it
 log_list.sort(cmp=lambda x,y: cmp(x[1], y[1]))
 if log_list is []:
     return 'No status available for this day and time.'

    #pull out the status
 status_to_return = log_list[-1][2].split('_')[-1].strip()

 return status_to_return

if __name__ == '__main__':
 in_file = open('a.log', 'rU')
 a_list = []

 for line in in_file:
  if line.strip() is not '': #handle whitespace
   a_list.append(line.split(' '))

 #convert string dates and times to datetime objects
 a_list = [ [datetime.datetime.strptime(el[0], '%d/%m/%Y'),
    datetime.datetime.strptime(el[1], '%H:%M:%S'), 
    el[2]] for el in a_list]


 a_date = datetime.datetime(2010, 7, 15)
 a_time = datetime.datetime(1900, 1, 1, 16, 1, 0)
 print getStatus(a_list, a_date, a_time)
导入日期时间
def getStatus(日志列表、dt、tm):
#筛选列表

log\u list=[a\u log\u entry for a\u log\u entry for a\u log\u entry in log\u list如果a\u log\u entry[0]==dt和a\u log\u entry[1]-1非音速且过于复杂的代码:您应该使用
strtime
来解析日期,而不是手动进行解析。
for line in file
是一种更清晰的文件迭代方式。
list[-1]
list.reverse();list[0]
好得多。你正在将整个文件读入内存,如果文件太大就不好了。
Status
只是一个元组(如果必须的话,称为tuple),你不需要一个新的类。总之,这不是正确的方法。实际上,我不知道数字是如何输入的,即第[0]行[1]因此,我们打开
文件
并迭代它的行:
对于文件中的行
。现在每个
都是一个字符串,我们在每个空间将其拆分,以在行上生成一个令牌列表:
行=行。拆分(“”
。这使得例如
['20/07/2010','13:07:26','U状态从脱机更改为可用']
。然后,
行[0]
将是日期(仍然是字符串格式),
行[1]
时间,以及
行[3]
状态字符串。如果导入模块
时间
,则不应使用名为
时间
的变量。有没有理由否决投票?我真的很好奇,我认为这是一段非常简洁的代码!由于比较日期的方式,如果想要检索2010年7月16日该用户的状态,这将不起作用(这将是脱机的)。但是,这种匹配在原始问题中没有提到。@Ashish:这个函数几乎总是返回错误的结果(不仅仅是因为“如果d==行\日期或t<行\时间”中的“或”).我已将
更改为
,但不太明白为什么会返回错误的结果。请温柔一点,我还没有喝咖啡P@Ashish::-)尝试
returnstatus(“15/07/2010”,“16:51:40”)
--这应该返回
离线
,但是函数错误地返回
。现在?是什么
import datetime
import time

def returnstatus(d, t):
    d = datetime.datetime.strptime(d, "%d/%m/%Y")
    t = time.strptime(t, "%H:%M:%S")
    f = open("log.txt")
    for line in f:
        line = line.split(" ")
        line_date = datetime.datetime.strptime(line[0], "%d/%m/%Y")
        line_time = time.strptime(line[1], "%H:%M:%S")
        if d != line_date and t >= line_time:
            continue
        # Returns the first occurrence. To get all store in a list or print.
        f.close()
        return line[2].split("_")[3]
import datetime

def getStatus(log_list, dt, tm):
 #filter the list
 log_list = [a_log_entry for a_log_entry in log_list if a_log_entry[0] == dt and a_log_entry[1] <= tm]

    #sort it
 log_list.sort(cmp=lambda x,y: cmp(x[1], y[1]))
 if log_list is []:
     return 'No status available for this day and time.'

    #pull out the status
 status_to_return = log_list[-1][2].split('_')[-1].strip()

 return status_to_return

if __name__ == '__main__':
 in_file = open('a.log', 'rU')
 a_list = []

 for line in in_file:
  if line.strip() is not '': #handle whitespace
   a_list.append(line.split(' '))

 #convert string dates and times to datetime objects
 a_list = [ [datetime.datetime.strptime(el[0], '%d/%m/%Y'),
    datetime.datetime.strptime(el[1], '%H:%M:%S'), 
    el[2]] for el in a_list]


 a_date = datetime.datetime(2010, 7, 15)
 a_time = datetime.datetime(1900, 1, 1, 16, 1, 0)
 print getStatus(a_list, a_date, a_time)