简体   繁体   中英

How to get the last date for each ID in a list?

I have a very interesting project which might benefit us all. I try to get the last datetime for every vehicle id in my_cars if that datetime is below my_time .

This is my_cars

my_cars = [['Audi', '111', 'White', 'True', 'NY', '06-09-2020', '10:11:32'], 
           ['Audi', '111', 'White', 'True', 'BS', '06-09-2020', '10:11:32'], 
           ['Volkswagen', '222', 'Blue', 'False', 'BR', '06-09-2020', '11:26:21'], 
           ['Mercedes', '333', 'Green', 'True', 'BE', '06-09-2020', '14:51:45'], 
           ['Mercedes', '333', 'Green', 'True', 'BE', '06-09-2020', '15:59:45']
           ['Opel', '555', 'Black', 'True', 'ER', '06-09-2020', '16:30:00']]

This is my code:

my_time =  datetime.datetime.strptime('2020-09-06 16:15:00', '%Y-%m-%d %H:%M:%S') 
date_times = []

results = []
date_times = []

for row in my_cars:
        date_time1 = row[-2] + row[-1] 
        date_time2 = datetime.datetime.strptime(row[-2] + row[-1] , '%d-%m-%Y%H:%M:%S') 
        date_times.append(date_time2)
        if date_time2 == max(dt for dt in date_times if dt < my_time):
            results.append(row)
        
print(results)

This is the output:

   [['Audi', '111', 'White', 'True', 'NY', '06-09-2020', '10:11:32'],  
    ['Audi', '111', 'White', 'True', 'BS', '06-09-2020', '10:11:32'], 
    ['Volkswagen', '222', 'Blue', 'False', 'BR', '06-09-2020', '11:26:21'], 
    ['Mercedes', '333', 'Green', 'True', 'BE', '06-09-2020', '14:51:45'], 
    ['Mercedes', '333', 'Green', 'True', 'BE', '06-09-2020', '15:59:45']]

This is the desired output:

   [['Audi', '111', 'White', 'True', 'NY', '06-09-2020', '10:11:32'],  
    ['Audi', '111', 'White', 'True', 'BS', '06-09-2020', '10:11:32'], 
    ['Volkswagen', '222', 'Blue', 'False', 'BR', '06-09-2020', '11:26:21'], 
    ['Mercedes', '333', 'Green', 'True', 'BE', '06-09-2020', '15:59:45']]

You can check if one datetime is lower than another using < :

if car_time < my_time:
  result.append(car)

So you wanna show a given vehicle only once and always with the freshest date. Given if your list is sorted by DateTime here is my solution:

new_cars = []
your_time =  datetime.strptime('2020-09-06 16:15:00', '%Y-%m-%d %H:%M:%S')

for car in reversed(cars):
    if your_time > datetime.strptime(car[-2] + car[-1] , '%d-%m-%Y%H:%M:%S'):
        for new_car in new_cars:
            # If the vehicle already in the list break the loop -> for else statement won't run ->
            # this car won't be added to the new list
            if car[:-2] == new_car[:-2]:
                break
        else:
            new_cars.append(car)

After reversing the new_car list the Output is:

[['Audi', '111', 'White', 'True', 'NY', '06-09-2020', '10:11:32']
['Audi', '111', 'White', 'True', 'BS', '06-09-2020', '10:11:32']
['Volkswagen', '222', 'Blue', 'False', 'BR', '06-09-2020', '11:26:21']
['Mercedes', '333', 'Green', 'True', 'BE', '06-09-2020', '15:59:45']]

If you 'cars' list not necessary sorted by the DateTime you can sort it very easily like that:

sorted(cars, key=lambda car: datetime.strptime(car[-2] + car[-1] , '%d-%m-%Y%H:%M:%S'))

In this case, the full code looks like this with your date limit :

from datetime import datetime

cars =   [['Audi', '111', 'White', 'True', 'NY', '06-09-2020', '10:11:32'],
    ['Audi', '111', 'White', 'True', 'BS', '06-09-2020', '10:11:32'],
    ['Volkswagen', '222', 'Blue', 'False', 'BR', '06-09-2020', '11:26:21'],
    ['Mercedes', '333', 'Green', 'True', 'BE', '06-09-2020', '14:51:45'],
    ['Mercedes', '333', 'Green', 'True', 'BE', '06-09-2020', '15:59:45'],
    ['Opel', '555', 'Black', 'True', 'ER', '06-09-2020', '16:30:00'],
]

# Use this only if the 'cars' list not necessary listed by the given datetime.
cars = sorted(cars, key=lambda car: datetime.strptime(car[-2] + car[-1] , '%d-%m-%Y%H:%M:%S'), reverse=True)

new_cars = []
your_time =  datetime.strptime('2020-09-06 16:15:00', '%Y-%m-%d %H:%M:%S')

for car in cars:
    if your_time > datetime.strptime(car[-2] + car[-1] , '%d-%m-%Y%H:%M:%S'):
        for new_car in new_cars:
            # If the vehicle already in the list break the loop -> for else statement won't run ->
            # this car won't be added to the new list
            if car[:-2] == new_car[:-2]:
                break
        else:
            new_cars.append(car)

The reversed Output once again:

[['Audi', '111', 'White', 'True', 'NY', '06-09-2020', '10:11:32']
['Audi', '111', 'White', 'True', 'BS', '06-09-2020', '10:11:32']
['Volkswagen', '222', 'Blue', 'False', 'BR', '06-09-2020', '11:26:21']
['Mercedes', '333', 'Green', 'True', 'BE', '06-09-2020', '15:59:45']]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM