【问题标题】:select certain files from directory从目录中选择某些文件
【发布时间】:2016-08-15 14:46:39
【问题描述】:

在同一个目录中,我有几个文件,其中一些是样本测量值,另一些是参考。它们看起来像这样:

blablabla_350.dat
blablabla_351.dat
blablabla_352.dat
blablabla_353.dat
...
blablabla_100.dat
blablabla_101.dat
blablabla_102.dat

以 350 到 353 结尾的是我的样本,以 100、101 和 102 结尾的是参考。好消息是样本和参考在数量上是连续的。

我想将它们分成两个不同的列表、示例和参考。

一个想法应该是这样的(还没有工作):

import glob

samples = []
references = []

ref = raw_input("Enter first reference name: ")
num_refs = raw_input("How many references are? ")

ref = sorted(glob.glob(ref+num_refs))

samples = sorted(glob.glob(*.dat)) not in references

因此参考列表将采用指定的第一个名称和后续名称(由指定的数字给出)。其余的都是样品。 任何想法如何将其放入 python 中?

【问题讨论】:

    标签: python glob


    【解决方案1】:

    您可以使用glob.glob 获取所有*.dat 文件的列表,然后使用带有条件的列表推导过滤该列表。在我的解决方案中,我使用正则表达式从文件名中提取数字作为文本。然后我将其转换为整数并检查该整数是否介于ref_fromref_to 之间。即使编号在ref_fromref_to 之间的一些参考文件丢失,这仍然有效。

    样本列表是通过集合操作得到的:它是从data_files的集合中去除references的结果。我们可以这样做,因为可以假定所有每个文件名都是唯一的。

    import glob
    import re
    
    samples = []
    references = []
    
    ref_from = 350
    ref_to = 353
    
    def ref_filter(filename):
        return ref_from <= int(re.search('_([0-9]+).dat', filename).group(1)) <= ref_to
    
    data_files = sorted(glob.glob("*.dat"))
    references = [filename for filename in data_files if ref_filter(filename)]
    samples = list(set(data_files) - set(references))
    
    print references
    print samples
    

    或者,如果您知道ref_fromref_to 之间的所有样本都将出现,您可以去掉函数ref_filter 并替换

    references = [filename for filename in data_files if ref_filter(filename)]
    

    references = ['blablabla_' + str(n) + '.dat' for n in xrange(ref_from, ref_to + 1)]
    

    【讨论】:

    • 非常感谢@nwk。你能解释一下函数的return语句吗?
    • 不客气!该语句返回TrueFalse,具体取决于从文件名中提取的数字(即blablabla_N.dat 中的N;见第一段)是否位于ref_fromref_to 之间。
    【解决方案2】:

    您可以使用glob.glob('*.dat') 获取所有文件的列表,然后根据您的条件对该列表进行切片。切片将从第一个引用名称的索引处开始,并且与引用的数量一样大。

    提取该切片以获取您的参考。删除该切片以获取您的样本。

    import glob
    
    samples = []
    references = []
    
    ref = raw_input("Enter first reference name: ")        # blablabla_100.dat
    num_refs = int(raw_input("How many references are? ")) # 3
    
    all_files = sorted(glob.glob('*.dat'))
    first_ref = all_files.index(ref)
    ref_files = all_files[first_ref:first_ref+num_refs]
    
    sample_files = all_files
    del sample_files[first_ref:first_ref+num_refs]
    del all_files
    
    print ref_files, sample_files
    

    结果:

    ['blablabla_100.dat', 'blablabla_101.dat', 'blablabla_102.dat'] ['blablabla_350.dat', 'blablabla_351.dat', 'blablabla_352.dat', 'blablabla_353.dat']
    

    【讨论】:

    • 谢谢@Robᵩ!不错的解决方案!
    【解决方案3】:

    您也可以在不使用glob 的情况下使用os 包:

    import os, re
    
    files = os.listdir(r'C:\path\to\files')
    samples, references = [], []
    for file in files:
        if re.search(r'blablabla_1\d{2}', file):
            references.append(file)
        elif re.serach(r'blablabla_3\d{2}', file):
            samples.append(file)
        else:
            print('{0} is neither sample nor reference'.format(file))
    

    【讨论】:

    • 不要忘记在正则表达式中使用r'' 或额外的反斜杠来转义\ds。
    【解决方案4】:

    试试类似的东西

    import glob
    
    samples = []
    references = []
    
    ref = raw_input("Enter first reference name: ")
    num_refs = int(raw_input("How many references are? "))
    
    for number in num_refs:
        refferences.append(ref+number)
    
    for filename in sorted(glob.glob('*.dat')):
        if filename not in refferences:
            samples.append(filename)
    

    【讨论】:

    • 既然num_refsstr,那么for number in num_refs: 有什么作用?
    • 这就是为什么我说“试试类似的东西”——这段代码没有 100% 完成。不过我添加了“int()”函数,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 2015-08-28
    • 1970-01-01
    • 2010-10-23
    • 2020-04-07
    • 1970-01-01
    相关资源
    最近更新 更多