#python #python-3.x #sorting #date #datetime
Вопрос:
Итак, у меня есть скрипт на python, в котором приведен отчет о каждом экземпляре ec2. У меня есть функция , которая сортирует сетевое время экземпляра, но каждый раз, когда я использую stftime для форматирования выходных данных даты, кажется, что сортировка и списки экземпляров выполняются в случайном порядке, а не по самому старому времени создания. Результат, который я получаю, выглядит следующим образом :
i-09dc54328002240ff,Aug 05 2021,asg-workxxx
i-048e92c5a4741d2b1,Mar 09 2017,False
i-0d649cebdf54bd2f4,Mar 12 2020,asg-dyyyyy
i-0ff596f1dc01b61d8,Mar 17 2021,asg-base-test
i-06db4eb158ad0b071,May 12 2021,False
i-0f285277529543462,May 18 2018,False
i-0f67cf99fb9f96c3f,Oct 14 2020,asg-elk-test
i-01734dfef0159c5c8,Oct 20 2020,asg-lb-test
i-0539c8dfc839cbfda,Oct 26 2020,asg-stand-base-test
Вы можете видеть, что дата создания не находится в отсортированном порядке.
Мой код выглядит следующим образом :
response = ec2_client.describe_instances(
MaxResults=10
)
# return json data from describe instances and filter what is needed
instances = (len(response['Reservations']))
header_row = 'InstanceID, CreationDateTime, AutoScalingGroupName' 'n'
for x in range(instances):
# Get InstanceId
instance_id = (response['Reservations'][x]
['Instances'][0]['InstanceId'])
# Get NetworkInterfacws AttatchTime
network_interface_id = (
response['Reservations'][x]['Instances'][0]['NetworkInterfaces'][0]['NetworkInterfaceId'])
network_interface_details = ec2_client.describe_network_interfaces(
NetworkInterfaceIds=[network_interface_id])
networkinterface_id_attachedtime = network_interface_details[
'NetworkInterfaces'][0]['Attachment']['AttachTime']
time_between_insertion = datetime.now(
timezone.utc) - networkinterface_id_attachedtime
# Get Autoscaling GroupName
tags = (response['Reservations'][x]['Instances'][0]['Tags'])
autoscaling_group_name = get_tag(tags, 'aws:autoscaling:groupName')
# print results
if time_between_insertion.days > max_age:
line = '{},{},{}'.format(
instance_id, formatted_date_networkinterface_id, autoscaling_group_name)
instances_list.append(line)
sorted_list= sorted(instances_list, key=lambda v: v.split(',')[1])
for instance in sorted_list:
print(instance) ```
Комментарии:
1. Какова ваша текущая производительность и ожидаемая производительность?
2. Вы сортируете список строк по подстрокам
sorted(instances_list, key=lambda v: v.split(',')[1])
, поэтому «дата» как таковая отсутствует. Обратите внимание, что в ваших выходных данных сначала отображаются даты месяца «А»…
Ответ №1:
Для разбора дат вы можете использовать datetime.datetime.strptime
:
import datetime # strptime
import operator # itemgetter
data_unparsed = ['i-09dc54328002240ff,Aug 05 2021,asg-workxxx',
'i-048e92c5a4741d2b1,Mar 09 2017,False',
'i-0d649cebdf54bd2f4,Mar 12 2020,asg-dyyyyy',
'i-0ff596f1dc01b61d8,Mar 17 2021,asg-base-test',
'i-06db4eb158ad0b071,May 12 2021,False',
'i-0f285277529543462,May 18 2018,False',
'i-0f67cf99fb9f96c3f,Oct 14 2020,asg-elk-test',
'i-01734dfef0159c5c8,Oct 20 2020,asg-lb-test',
'i-0539c8dfc839cbfda,Oct 26 2020,asg-stand-base-test']
data = [((row := s.split(','))[0], datetime.datetime.strptime(row[1], '%b %d %Y'), row[2]) for s in data_unparsed]
data_sorted = sorted(data, key=operator.itemgetter(1))
print(data_sorted)
# [('i-048e92c5a4741d2b1', datetime.datetime(2017, 3, 9, 0, 0), 'False'),
# ('i-0f285277529543462', datetime.datetime(2018, 5, 18, 0, 0), 'False'),
# ('i-0d649cebdf54bd2f4', datetime.datetime(2020, 3, 12, 0, 0), 'asg-dyyyyy'),
# ('i-0f67cf99fb9f96c3f', datetime.datetime(2020, 10, 14, 0, 0), 'asg-elk-test'),
# ('i-01734dfef0159c5c8', datetime.datetime(2020, 10, 20, 0, 0), 'asg-lb-test'),
# ('i-0539c8dfc839cbfda', datetime.datetime(2020, 10, 26, 0, 0), 'asg-stand-base-test'),
# ('i-0ff596f1dc01b61d8', datetime.datetime(2021, 3, 17, 0, 0), 'asg-base-test'),
# ('i-06db4eb158ad0b071', datetime.datetime(2021, 5, 12, 0, 0), 'False'),
# ('i-09dc54328002240ff', datetime.datetime(2021, 8, 5, 0, 0), 'asg-workxxx')]
Альтернативно, в качестве однострочного:
data_sorted = sorted(data_unparsed, key=lambda s: datetime.datetime.strptime(s.split(',')[1], '%b %d %Y'))
print(data_sorted)
# ['i-048e92c5a4741d2b1,Mar 09 2017,False',
# 'i-0f285277529543462,May 18 2018,False',
# 'i-0d649cebdf54bd2f4,Mar 12 2020,asg-dyyyyy',
# 'i-0f67cf99fb9f96c3f,Oct 14 2020,asg-elk-test',
# 'i-01734dfef0159c5c8,Oct 20 2020,asg-lb-test',
# 'i-0539c8dfc839cbfda,Oct 26 2020,asg-stand-base-test',
# 'i-0ff596f1dc01b61d8,Mar 17 2021,asg-base-test',
# 'i-06db4eb158ad0b071,May 12 2021,False',
# 'i-09dc54328002240ff,Aug 05 2021,asg-workxxx']
Соответствующая документация:
Комментарии:
1. Я только что попробовал это, и я получаю эту ошибку : ошибка повышения значения(«данные о времени %r не соответствуют формату %r» % Ошибка значения: данные о времени ‘2020-03-12 10:07:07 00:00’ не соответствует формату «%b %d %Y» @Stef
2. @devdude, да, формат, который я указал, соответствует строкам типа
"Aug 05 2021"
. Если строки разные, например"2020-03-12 10:07:07 00:00"
, вам нужен другой формат. Документация, которую я связал, объясняет, как написать формат (возможно"%Y-%m-%d %H:%M:%S%z"
, в случае ‘2020-03-12 10:07:07 00:00’). Или вы можете попробовать вообще не указывать формат и позволить датам-времени разобраться в этом. Опасность в этом случае заключается в том, что вы должны убедиться, что дата и время не путают день и месяц (т. е. 07-12-это 12 июля, а не 7 декабря).3. Если у вас есть только эти два формата, вы можете использовать
try / except
блок, чтобы попытаться применить формат, а если это не удастся, попробуйте применить второй формат.