【问题标题】:Python/Itertools: Get latest file by namePython/Itertools:按名称获取最新文件
【发布时间】:2018-08-07 21:14:05
【问题描述】:

我有一个目录中的文件名列表,我想只保留最新版本。该列表如下所示:

['file1-v1.csv', 'file1-v2.csv', 'file2-v1.txt', ...]

我只想根据版本(文件名中 - 之后的部分)和 txt 文件保留最新的 csv 文件。

输出将是[''file1-v2.csv', 'file2-v1.txt', ...]

我有一个需要使用集合的解决方案,但我正在寻找一种简单的 Pythonic 方法来执行此操作。可能使用itertoolsgroupby

更新:目前的解决方案

我已经能够做一些初步工作来获得一个类似的列表

lst = [('file1', 'csv', 'v1','<some data>'), ('file2', 'csv', 'v2','<some data>'), ...]

我想按索引01 处的元素分组,但只提供最大索引2 的元组。

可能是这样的:

files = list(item for key, group in itertools.groupby(files, lambda x: x[0:2]) for item in group)
# Maximum over 3rd index element in each tuple does not work
files = max(files, key=operator.itemgetter(2))

另外,我觉得下面应该可以工作,但它没有正确选择最大值

[max(items, key=operator.itemgetter(2)) for key, items in itertools.groupby(files, key=operator.itemgetter(0, 1))]

【问题讨论】:

  • 您也应该发布您尝试过的当前代码
  • list中是否保证文件的所有版本都是连续的?
  • @ShadowRanger 不,他们不是。我应该可以做类似f_tuple = [(f.split('-')[0], f.split('-')[1]) for f in lst]; sorted(f_tuple, key=lambda x: x[1])
  • 所有文件都有相同的扩展名吗? file1-v1.csvfile1-v1.txt 是否被视为两个不同的文件?
  • @bro-grammer,是的,它们是不同的文件。所以不同扩展名的文件会被区别对待。

标签: python iterator itertools


【解决方案1】:

你可以试试这个:

a = ['file1-v1.csv', 'file1-v2.csv', 'file2-v1.txt','file4-v1.csv','file2-v2.txt','file2-v3.txt']
d = {}
for i in a:
    x = i.split("-")
    d[x[0]]= x[1]
    if x[0] in d:
        d[x[0]] = x[1]
    else:
        d[x[0]] = x[1] 

for x,y in d.items():
    print('-'.join((x,y)))

【讨论】:

    【解决方案2】:

    我会这样做:

    import os
    import itertools
    
    filenames = ['file1-v1.csv', 'file1-v2.csv', 'file1-v3.jpg', 'file2-v1.txt']
    
    
    def split_filename(filename):
        basename, ext = os.path.splitext(filename)
        root, version = basename.rsplit('-v', 1)
    
        return root, ext, int(version)
    
    def filter_latest_versions(filenames):
        parsed_filenames = sorted(map(split_filename, filenames))
    
        for _, matches in itertools.groupby(parsed_filenames, key=lambda f: f[:2]):
            root, ext, version = tuple(matches)[-1]
    
            yield '{}-v{}{}'.format(root, version, ext)
    

    它与您现在发布的解决方案没有太大区别,但它确实可以正确分类不同的扩展名并处理名称中带有破折号的文件名。

    【讨论】:

    • filenames = ['file1-v1.csv', 'file1-v2.csv', 'file1-v11.csv'] 好像坏掉了?
    猜你喜欢
    • 2019-01-16
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    相关资源
    最近更新 更多