Сортировка объектов даты в списках python в неправильном порядке

#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 блок, чтобы попытаться применить формат, а если это не удастся, попробуйте применить второй формат.