简体   繁体   English

根据日期和第一个元素对列表列表进行排序

[英]Sort list of lists based on date and first element

ArrayData = [['a', 'ad', '02/10/2021  7:39:19 am', 'Rank:1'],
             ['b', 'db', '02/10/2021 6:25:20 am', 'Rank:2'],
             ['a', 'sd', '02/10/2021  5:39:19 am', 'Rank:3'],
             ['b', 'esas', '02/10/2021 6:25:20 am', 'Rank:1'],
             ['a', 'aser', '02/10/2021  9:39:19 am', 'Rank:2'],
             ['d', 'ssss', '02/10/2021  11:39:19 am', 'Rank:1']]

The script should脚本应该

  1. Sort the same group (eg. sort group 'a' first, followed by group 'b', 'c', 'd') base on the time.根据时间对同一组进行排序(例如,首先对“a”组进行排序,然后是“b”、“c”、“d”组)。 More recent times and dates have higher ranks.最近的时间和日期具有更高的排名。

  2. Update the "rank" in each subarray更新每个子数组中的“排名”

Expected output:预计 output:

[['d', 'ssss', '02/10/2021  11:39:19 am', 'Rank:1'],
 ['b', 'esas', '03/10/2021 6:25:20 am', 'Rank:2'],
 ['b', 'db', '02/10/2021 6:25:20 am', 'Rank:1'],
 ['a', 'aser', '02/10/2021  9:39:19 am', 'Rank:3'],
 ['a', 'ad', '02/10/2021  7:39:19 am', 'Rank:2'],
 ['a', 'sd', '02/10/2021  5:39:19 am', 'Rank:1']]

This is the current script I wrote这是我写的当前脚本

import operator
result = sorted(ArrayData, key=operator.itemgetter(2), reverse=True)
print(result)

May I know how to improve it?我可以知道如何改进它吗?

Note that this converts your datetime strings to datetime.datetime objects.请注意,这会将您的日期时间字符串转换为datetime.datetime对象。 This may or may not be desirable, but is at least recommended if you plan on doing any other operations involving those dates.这可能是可取的,也可能不是可取的,但如果您计划进行涉及这些日期的任何其他操作,至少建议这样做。 If you really want them as strings, see the commented line of code.如果您确实希望将它们作为字符串,请参阅代码的注释行。

Note also that I'm assuming that your dates are dd/mm/yyyy .另请注意,我假设您的日期是dd/mm/yyyy If they are mm/dd/yyyy instead, you'll need to switch the %d and %m in DATETIME_FORMAT .如果它们是mm/dd/yyyy ,则需要在DATETIME_FORMAT中切换%d%m

import datetime
import itertools
from operator import itemgetter as get


# Assumes day/month/year, switch %d and %m if not
DATETIME_FORMAT = "%d/%m/%Y %I:%M:%S %p"


def parse_datetimes(data: list) -> list:
    result = []
    for first, second, timestamp, rank in data:
        timestamp = datetime.datetime.strptime(timestamp, DATETIME_FORMAT)
        result.append([first, second, timestamp, rank])
    return result


def custom_sort(data: list) -> list:
    # Convert datetime strings to datetime objects, then sort by first element
    sorted_data = sorted(parse_datetimes(data), key=get(0), reverse=True)

    # Re-rank each group sorted by date
    result = []
    for _, group in itertools.groupby(sorted_data, key=get(0)):
        ranked_group = []
        sorted_group = sorted(group, key=get(2))
        for rank, (*item, _) in enumerate(sorted_group, 1):
            # item[2] = item[2].strftime(DATETIME_FORMAT)
            ranked_group.append([*item, f"Rank:{rank}"])
        result.extend(ranked_group[::-1])
    return result

Demo:演示:

>>> custom_sort(ArrayData)
[['d', 'ssss', datetime.datetime(2021, 10, 2, 11, 39, 19), 'Rank:1'],
 ['b', 'esas', datetime.datetime(2021, 10, 2, 6, 25, 20), 'Rank:2'],
 ['b', 'db', datetime.datetime(2021, 10, 2, 6, 25, 20), 'Rank:1'],
 ['a', 'aser', datetime.datetime(2021, 10, 2, 9, 39, 19), 'Rank:3'],
 ['a', 'ad', datetime.datetime(2021, 10, 2, 7, 39, 19), 'Rank:2'],
 ['a', 'sd', datetime.datetime(2021, 10, 2, 5, 39, 19), 'Rank:1']]

The other solutions seemed too complicated to me.其他解决方案对我来说似乎太复杂了。 If you want you can use string comparison without resorting to datetime s.如果你愿意,你可以使用字符串比较而不求助于datetime s。

Here's a custom solution I rigged together that seems to give the desired output:这是我组装在一起的自定义解决方案,似乎可以提供所需的 output:

from collections import defaultdict
from pprint import pprint
from typing import DefaultDict, List


array_data = [['d', 'ssss', '11-04-20', 'Rank:1'],
              ['a', 'ad', '10-13-20', 'Rank:1'],
              ['b', 'db', '12-13-20', 'Rank:2'],
              ['a', 'sd', '05-13-20', 'Rank:3'],
              ['b', 'esas', '12-14-20', 'Rank:1'],
              ['a', 'aser', '12-13-20', 'Rank:2']]


final_array = []
group_to_data: DefaultDict[str, List[List[str]]] = defaultdict(list)

for data in array_data:
    group_to_data[data[0]].append(data)


def sort_fn(x):
    """Sort by group, then by date"""
    month, day, year = x[2].split('-')
    return f'{year}{month}{day}'


for _, data in sorted(group_to_data.items(), reverse=True):
    # sorts sub-list for each group
    data.sort(key=sort_fn)

    # iterating over data in reverse order, since that's how we want it in
    # final result
    for i in range(len(data) - 1, -1, -1):
        new_rank = f"Rank:{i + 1}"
        item = data[i]
        item[-1] = new_rank
        final_array.append(item)

pprint(final_array)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何根据内部列表的长度对列表列表进行排序,但如果两个内部列表相等,则根据内部列表的第一个元素进行排序 - How to sort a list of lists based on the length of the inner lists, but if two inner lists are equal then sort based on first element of inner list 根据内部列表的第N个元素的总和对列表列表进行排序 - Sort list of lists of lists based on sum of Nth element of inner lists 基于列表python列表的第一个元素的平均值 - Average based on first element of list of lists python 基于子列表中的第一个元素的列表的集群列表 - cluster list of lists based on the first element in the sublist 根据长度重复列表列表的第一个元素 - Repeat First element of a List of Lists Based on Length Python - 基于内部列表的第一个元素对列表列表中的元素求和 - Python - Summing elements on list of lists based on first element of inner lists 根据每个列表的第一个元素从列表中删除项目 - Removing an item from a list of lists based on each of the lists first element Python:如何按最常见的第一个元素对列表列表进行排序? - Python: How to sort a list of lists by the most common first element? python排序列表来自1个基于日期元素的列表 - python sort lists from 1 list based on date elements 基于日期部分反转的 Python 列表排序列表 - Python sort list of lists partially reverse based on date
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM