首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我在python中的条件不被满足?

为什么我在python中的条件不被满足?
EN

Stack Overflow用户
提问于 2016-09-21 19:08:44
回答 3查看 64关注 0票数 0

我有一个按创建日期排序的文件名列表。这些文件在文件名中包含其创建日期和时间的日期时间。我正在尝试为特定时间后的所有文件创建一个子列表。

完整的文件列表-

代码语言:javascript
复制
Allfilenames = ['CCN-200 data 130321055347.csv',
'CCN-200 data 130321060000.csv',
'CCN-200 data 130321063235.csv',
'CCN-200 data 130321070000.csv',
'CCN-200 data 130321080000.csv',
'CCN-200 data 130321090000.csv',
'CCN-200 data 130321100000.csv',
'CCN-200 data 130321110000.csv',
'CCN-200 data 130321120000.csv',
'CCN-200 data 130321130000.csv',
'CCN-200 data 130321140000.csv',
'CCN-200 data 130321150000.csv']

positions [19:24]以hhmmss格式提供时间。我正在使用

代码语言:javascript
复制
filenames = [s for s in Allfilenames if os.path.basename(s)[19:24] >= TOffRound]

TOffRound = "080000"

结果应该是在或08:00:00创建的所有文件名的列表,但是结果列表缺少"080000“文件。

代码语言:javascript
复制
filenames = ['CCN-200 data 130321090000.csv',
'CCN-200 data 130321100000.csv',
'CCN-200 data 130321110000.csv',
'CCN-200 data 130321120000.csv',
'CCN-200 data 130321130000.csv',
'CCN-200 data 130321140000.csv',
'CCN-200 data 130321150000.csv']

为什么条件中的=部分不返回true,并在我的列表中返回'CCN-200 data 130321080000.csv‘?请注意,为了清楚起见,我在这里仅显示了基本名称。

EN

回答 3

Stack Overflow用户

发布于 2016-09-21 19:31:33

我建议使用一种更强大的方法来测试文件名的时间部分,而不是将时间部分作为字符串进行检查。这包括提取文件名的日期部分,检索时间值,并将其作为时间对象与您指定的时间进行比较。

代码语言:javascript
复制
import re
import datetime

TOffRound = datetime.time(8, 0)
filenames = []

for s in Allfilenames:
  datestr = re.search("[\d]{12}", s).group(0)
  dateobj = datetime.datetime.strptime(datestr,"%y%m%d%H%M%S")
  timeobj = dateobj.time()
  if timeobj >= TOffRound:
    filenames.append(s)
票数 1
EN

Stack Overflow用户

发布于 2016-09-21 19:19:39

您的文件名中存在来自索引19:25而不是19:24hhmmss。因此,从filename获取hhmmss的正确语句是:

代码语言:javascript
复制
filenames = [s for s in Allfilenames if os.path.basename(s)[19:25] >= TOffRound]
票数 0
EN

Stack Overflow用户

发布于 2016-09-21 21:16:13

正如其他人所建议的那样,给出的代码的问题是您遗漏了最后一个数字。在对列表进行分片时,不考虑在:后面给出的"stop“数字。

代码语言:javascript
复制
(eg):
>> a = "hello world"
>> print a[0:4]
hell
>> print a[0:5]
hello

因此,更改代码中的这一行就可以了:

代码语言:javascript
复制
filenames = [s for s in Allfilenames if os.path.basename(s)[19:25] >= TOffRound]

但是,您正在做的事情根本没有可伸缩性。这并不容易维护,也不能处理任何稍有不同的文件。代码可以这样转换:

代码语言:javascript
复制
def filter_files(file_list, TOffRound):
    text_length = len(TOffRound)
    return [file_name for file_name in file_list if file_name[-text_length:] >= TOffRound]

无论文件名的大小如何,这都将起作用。

我还建议您根据文件的修改时间获取文件列表,这些文件可以使用os.statos.path.getmtime获取,并采取相应的操作,而不是使用文件名。文件名是一个字符串,即使它可以支持较旧或较新的文件,但通常不是一个好的使用方式。您正在将文件名的时间戳转换为字符串。然后将该字符串转换回时间戳,并在正常情况下进行转换。相反,如果您选择文件修改时间,您可以只停留在日期和时间格式,而不是需要完成的转换。这有几个优点:

  • 文件名或任何显式参数可以随着时间的推移而更改,但您不需要一次又一次地更改逻辑
  • 基于文件的时间戳确实存在用于这些目的。因此,它们确实提供了更多的控制。例如,如果您希望选择特定范围的文件,仅在特定时间段创建或修改文件?易于处理文件时间戳。
  • 这将时间逻辑从文件名中分离出来,因此您可以根据它们的用途对它们进行更有意义的命名,从而简化一段时间内代码的维护。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39614869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档