我想遍历列表中包含的字典,并删除早于特定日期的ARRIVAL DATE TIME
项。
我已经审查了类似的先前问题(similar question,another one,and another one),但鉴于数据结构的复杂性,我正在努力应用建议的解决方案。
到目前为止,这是我尝试过的。解决方案似乎我需要遍历数据结构的重复项,但是我该怎么做呢?
from datetime import datetime
ferry = [ {
"NAME":"SNAV Atlair",
"LAST CALLING PORT":"Casamicciola Terme",
"CALLING PORTS HISTORY":{
"MONDAY":[
{
"PORT":"Casamicciola Terme",
"ARRIVAL DATE TIME":"2019-03-19 20:12:10"
},
{
"PORT":"Casamicciola Terme",
"ARRIVAL DATE TIME":"2019-03-19 16:12:10"
}
] ,
"TUESDAY":[
{
"PORT":"Casamicciola Terme",
"ARRIVAL DATE TIME":"2019-03-19 20:12:10"
}
],
"WEDNESDAY":[
],
"THURSDAY":[
],
"FRIDAY":[
],
"SATURDAY":[
],
"SUNDAY":[
]
}
}]
datetime_last_position = '2019-03-23 12:50:00'
for entry in list(ferry):
for i in range(len(entry['CALLING PORTS HISTORY']['MONDAY'])):
if datetime.strptime(entry['CALLING PORTS HISTORY']['MONDAY'][i]['ARRIVAL DATE TIME'], '%Y-%m-%d %H:%M:%S').date() < datetime.strptime(datetime_last_position, '%Y-%m-%d %H:%M:%S').date():
del entry['CALLING PORTS HISTORY']['MONDAY'][i]
答案 0 :(得分:2)
从列表中删除元素的另一种方法(如果您以相反的顺序进行迭代(如another answer中指出的那样,则可以这样做)是仅创建一个仅包含要保留在其中的元素的新列表每种情况:
from datetime import datetime
ferry = [...]
datetime_last_position = '2019-03-23 12:50:00'
ref_date = datetime.strptime(datetime_last_position, '%Y-%m-%d %H:%M:%S').date()
for entry in list(ferry):
callings = entry['CALLING PORTS HISTORY']
for day in callings:
callings[day][:] = [call for call in callings[day]
if datetime.strptime(call['ARRIVAL DATE TIME'], '%Y-%m-%d %H:%M:%S').date() >= ref_date]
print(ferry)
# [{'NAME': 'SNAV Atlair', 'LAST CALLING PORT': 'Casamicciola Terme', 'CALLING PORTS HISTORY': {'MONDAY': [], 'TUESDAY': [], 'WEDNESDAY': [], 'THURSDAY': [], 'FRIDAY': [], 'SATURDAY': [], 'SUNDAY': []}}]
此外,请注意,您当前正在编辑ferry
中的对象,因此list(ferry)
中的for entry in list(ferry):
实际上并没有做任何事情。如果要使用保留旧对象的已修改对象创建新列表,则需要制作每个对象的副本,或者在应用修改之前只使用copy.deepcopy
。
答案 1 :(得分:1)
如果您以相反的顺序遍历项目,则可以安全地删除它们:
for i in range(len(entry['CALLING PORTS HISTORY']['MONDAY'])-1, -1, -1):
if datetime.strptime(entry['CALLING PORTS HISTORY']['MONDAY'][i]['ARRIVAL DATE TIME'], '%Y-%m-%d %H:%M:%S').date() < datetime.strptime(datetime_last_position, '%Y-%m-%d %H:%M:%S').date():
del entry['CALLING PORTS HISTORY']['MONDAY'][i]
当然,您可能不想在每个工作日都重写它,所以这样可能会更好:
for weekday in entry["CALLING PORTS HISTORY"]:
for i in range(len(entry['CALLING PORTS HISTORY'][weekday])-1, -1, -1):
if datetime.strptime(entry['CALLING PORTS HISTORY'][weekday][i]['ARRIVAL DATE TIME'], '%Y-%m-%d %H:%M:%S').date() < datetime.strptime(datetime_last_position, '%Y-%m-%d %H:%M:%S').date():
del entry['CALLING PORTS HISTORY'][weekday][i]
答案 2 :(得分:1)
如果应删除条目的元素,则可以“跳过”该元素,然后将其替换为下一个可接受的元素,然后将该列表缩短为“未跳过”元素的数量:
datetime_last_position = '2019-03-23 12:50:00'
for entry in list(ferry):
ptr = 0 # index where algorithm will store element
for value in entry['CALLING PORTS HISTORY']['MONDAY']:
if datetime.strptime(
entry['CALLING PORTS HISTORY']['MONDAY'][i]['ARRIVAL DATE TIME'],
'%Y-%m-%d %H:%M:%S'
).date() < datetime.strptime(datetime_last_position, '%Y-%m-%d %H:%M:%S').date():
pass # say, skip element
else:
# write then increment pointer
entry['CALLING PORTS HISTORY']['MONDAY'][ptr] = value
ptr += 1
# shorten a list
entry['CALLING PORTS HISTORY']['MONDAY'] = entry['CALLING PORTS HISTORY']['MONDAY'][:ptr]
ferry
Out:
[{'CALLING PORTS HISTORY': {'FRIDAY': [],
'MONDAY': [],
'SATURDAY': [],
'SUNDAY': [],
'THURSDAY': [],
'TUESDAY': [{'ARRIVAL DATE TIME': '2019-03-19 20:12:10',
'PORT': 'Casamicciola Terme'}],
'WEDNESDAY': []},
'LAST CALLING PORT': 'Casamicciola Terme',
'NAME': 'SNAV Atlair'}]
它具有O(n)
的复杂性,并且没有意外行为。
答案 3 :(得分:0)
根据我对您的问题的了解,您希望删除每个工作日列表中ARRIVAL DATE TIME
早于给定日期的元素。
由于您提供的日期是字符串,因此我们需要创建一个函数以将它们转换为datetime对象:
strToDate = lambda date_string: datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S')
从那里开始,循环遍历各种元素(假设您的结构是恒定的),然后根据需要为每个工作日创建一个新列表,这很简单。您可以就地修改字典,但不能修改列表,这就是为什么我在下面使用列表理解来创建新列表的原因:
for item in ferry:
for weekday in item["CALLING PORTS HISTORY"]:
item["CALLING PORTS HISTORY"][weekday] = [subitem
for subitem in item["CALLING PORTS HISTORY"][weekday]
if strToDate(subitem["ARRIVAL DATE TIME"]) >= date]
这将保留日期早于date
的那些对象,同时消除那些日期不早于python
的对象,从而得到您想要的结构!