【问题标题】:Filtering a list containing date Strings过滤包含日期字符串的列表
【发布时间】:2020-06-14 14:17:53
【问题描述】:

下面是一个示例列表,其中每个元素都有一个名称(例如XXX)和关联的日期(例如20200115

[XXX_20200115, XXX_20200116, YYY_20200116, ZZZ_20200116, ZZZ_20200117] 

我想从列表中删除所有同名但日期较旧的元素。例如,我想删除XXX_20200115,因为XXX_20200116 已经存在且日期最近。

所以我的最终输出应该是:

[ XXX_20200116, YYY_20200116, ZZZ_20200117]

直到现在我写了这段代码:

from collections import defaultdict

def list_duplicates(seq):
    tally = defaultdict(list)
    for i,item in enumerate(seq):
        tally[item].append(i)
    return ((key,locs) for key,locs in tally.items() 
                            if len(locs)>1)


def filterModules(mylist):
    names = []
    timestamps =  []

    for module in mylist:
         splittedName = module.rsplit('_', 1)
         names.append(splittedName[0])
         timestamps.append(splittedName[1])

    duplicates = []
    for dup in sorted(list_duplicates(names)):
        duplicate = {}
        duplicate['name'] = dup[0]
        duplicate['indexs'] = dup[1]
        duplicates.append(duplicate)

这给了我与他们的索引重复。

我的问题是,我的目标是为这个问题编写最少的代码,但我的代码越来越大,而且似乎我正在以低效的方式解决这个问题。有人能告诉我用最少的代码解决这个问题的更优化方法吗?

【问题讨论】:

    标签: python python-3.x list date filter


    【解决方案1】:

    首先根据前 3 个字母对元素进行分组,然后从子列表中获取max()。如果是字符串,python 也会根据整数取最大值:

    from itertools import groupby
    
    l1 = ["XXX_20200115", "XXX_20200116", "YYY_20200116", "ZZZ_20200116", "ZZZ_20200117"]
    
    l2 = [list(g) for k, g in groupby(l1, key=lambda x: x.split("_")[0])]
    
    new_l = [max(i) for i in l2]
    
    print(new_l)
    

    【讨论】:

    • 尽管我喜欢这种方法,但我认为将名称限制为前 3 个字母可能是一个错误的假设。我相信必须有一种方法来概括这一点。
    • 当名称可以有可变长度时,如何修改此代码?例如,元素可以是“XXX_20200115”或“YYYYYYYYY_20200116”。
    • 如果您确定名称和日期由标识符分隔,在本例中为“下划线”。您可以按“下划线”分割并使用第一个元素。
    • @VikasP,你能解释一下 max() 函数如何能够给出最新日期的元素吗?使用这个函数可靠吗?
    • @Anudocs 在您的情况下,日期字符串的格式为 YYYYMMDD 格式,我们可以将其视为一个整数值。而python将根据整数值取最大值。
    【解决方案2】:

    我尝试为此使用字典,其中XXXYYY 等可以是键,值可以是日期。这就是实现的样子。

    dt = ['XXX_20200115', 'XXX_20200116', 'YYY_20200116', 'ZZZ_20200116', 'ZZZ_20200117'] 
    
    dt = [tuple(i.split('_'))for i in dt]
    
    new_dt = {}
    
    for i,j in dt:
        if i not in new_dt.keys():
            new_dt[i]=j
        else:
            if j>new_dt[i]:
                new_dt[i]=j
    
    print(new_dt)
    

    这会给你

    {'XXX': '20200116', 'YYY': '20200116', 'ZZZ': '20200117'}
    

    最后,如果您想转换为原始格式,则只需附加键和值并使用

    将其变为数组
    new_dt = ["{}_{}".format(i,new_dt[i]) for i in new_dt]
    

    这会给

    ['XXX_20200116', 'YYY_20200116', 'ZZZ_20200117']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-23
      • 2019-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-01
      • 1970-01-01
      相关资源
      最近更新 更多