给定一个包含项目列表的列表 projects,以及一个包含每个项目关联任务的列表 tasks。其中,有些项目可能没有任务,有些任务也可能尚未完成。某些项目还可能有多个任务。现在,我们需要生成一个列表,其中每个子列表包含一个项目、任务的 earliest start date 和 latest task end date。如果一个任务尚未完成,则 end date 为 None。如果某个项目没有任务,则 start date 和 end date 都为 None。
解决方案
1. 问题分析
我们首先分析一下代码中存在的问题。
item[0] not in tasks
:这是判断是否存在项目对应的任务的检查条件。然而,tasks
是一个列表,而不是一个字典。因此,代码无法正确地进行此检查。start_date = [x[1:-1] for x in tasks if x[0] == item[0]]
:这一行代码中存在一个潜在的问题。它尝试获取任务的 start date,但实际上 tasks 中的每个子列表包含三个值:[Project ID, Start Date, End Date]
。因此,正确的方法应该是start_date = [x[1] for x in tasks if x[0] == item[0]]
。end_date = [x[-1] for x in tasks if x[0] == item[0]]
:类似地,这行代码中也存在类似的问题。它尝试获取任务的 end date,但实际上 tasks 中的每个子列表包含三个值:[Project ID, Start Date, End Date]
。因此,正确的方法应该是end_date = [x[2] for x in tasks if x[0] == item[0]]
。
2. 更优解决方案
我们可以使用以下改进后的代码来解决上述问题:
import datetime
tasks = [['ID1', datetime.datetime( 2015, 1, 1), datetime.datetime( 2015, 1, 2)],
['ID1', datetime.datetime( 2015, 10, 1), None],
['ID2', datetime.datetime( 2015, 1, 1), datetime.datetime( 2015, 1, 3)]]
projects = [['ID1'], ['ID2'], ['ID3']]
for key, item in enumerate(projects):
if item[0] not in tasks:
item.append(None)
item.append(None)
else:
start_date = [x[1] for x in tasks if x[0] == item[0]]
if start_date.count(None) != 0: #checks to see if there is a None value
item.append(None)
else:
item.append(min(start_date))
end_date = [x[2] for x in tasks if x[0] == item[0]]
if end_date.count(None) != 0: #checks to see if there is a None value
item.append(None)
else:
item.append(max(end_date))
print(projects)
3. 使用字典
我们也可以将 tasks 转换为字典,然后使用字典的键值来匹配项目和任务。这可以提高代码的可读性和效率。
import datetime
tasks = {'ID1': [[datetime.datetime( 2015, 1, 1), datetime.datetime( 2015, 1, 2)],
[datetime.datetime( 2015, 10, 1), None]],
'ID2': [[datetime.datetime( 2015, 1, 1), datetime.datetime( 2015, 1, 3)]]}
projects = [['ID1'], ['ID2'], ['ID3']]
for key, item in enumerate(projects):
if item[0] not in tasks:
item.append(None)
item.append(None)
else:
start_date = [x[0] for x in tasks[item[0]]]
if start_date.count(None) != 0: #checks to see if there is a None value
item.append(None)
else:
item.append(min(start_date))
end_date = [x[1] for x in tasks[item[0]]]
if end_date.count(None) != 0: #checks to see if there is a None value
item.append(None)
else:
item.append(max(end_date))
print(projects)
最终,无论选择哪种解决方案,都可以高效地提取列表中每个列表的最小和最大值。