【问题标题】:Reading files in a particular order in python在python中以特定顺序读取文件
【发布时间】:2016-12-23 04:45:24
【问题描述】:

假设我在一个文件夹中有三个文件:file9.txt、file10.txt 和 file11.txt,我想以这个特定的顺序阅读它们。谁能帮我解决这个问题?

现在我正在使用代码

import glob, os
for infile in glob.glob(os.path.join( '*.txt')):
    print "Current File Being Processed is: " + infile

它首先读取 file10.txt,然后是 file11.txt,然后是 file9.txt。

有人可以帮我如何获得正确的订单吗?

【问题讨论】:

    标签: python file order-of-execution


    【解决方案1】:

    文件系统上的文件未排序。您可以使用sorted() function 自己对生成的文件名进行排序:

    for infile in sorted(glob.glob('*.txt')):
        print "Current File Being Processed is: " + infile
    

    请注意,您的代码中的 os.path.join 调用是无操作的;只有一个参数,它什么也不做,只是返回原样的参数。

    请注意,您的文件将按字母顺序排序,这会将10 放在9 之前。您可以使用自定义键功能来改进排序:

    import re
    numbers = re.compile(r'(\d+)')
    def numericalSort(value):
        parts = numbers.split(value)
        parts[1::2] = map(int, parts[1::2])
        return parts
    
     for infile in sorted(glob.glob('*.txt'), key=numericalSort):
        print "Current File Being Processed is: " + infile
    

    numericalSort 函数将文件名中的任何数字拆分,将其转换为实际数字,并返回结果进行排序:

    >>> files = ['file9.txt', 'file10.txt', 'file11.txt', '32foo9.txt', '32foo10.txt']
    >>> sorted(files)
    ['32foo10.txt', '32foo9.txt', 'file10.txt', 'file11.txt', 'file9.txt']
    >>> sorted(files, key=numericalSort)
    ['32foo9.txt', '32foo10.txt', 'file9.txt', 'file10.txt', 'file11.txt']
    

    【讨论】:

    • 嗨。不幸的是, sorted 函数不会改变顺序。
    • @user1620012:更新了我的答案以改进排序顺序。
    • 嗨..实际上我的文件的名称类似于.. text-text9-text.txt、text-text10-text.txt 等。
    • @user1620012:我的排序功能可以很好地处理这些。
    • @user1620012:太好了。 :-) 不要忘记将最能帮助您的答案标记为已接受(点击投票分数下方的绿色“V”标记)。
    【解决方案2】:

    您可以将glob.glob( ... ) 表达式包装在sorted( ... ) 语句中并对生成的文件列表进行排序。示例:

    for infile in sorted(glob.glob('*.txt')):
    

    您可以给sorted 一个比较函数,或者更好的是,使用key= ... 参数给它一个用于排序的自定义键。

    例子:

    有以下文件:

    x/blub01.txt
    x/blub02.txt
    x/blub10.txt
    x/blub03.txt
    y/blub05.txt
    

    以下代码将产生以下输出:

    for filename in sorted(glob.glob('[xy]/*.txt')):
            print filename
    # x/blub01.txt
    # x/blub02.txt
    # x/blub03.txt
    # x/blub10.txt
    # y/blub05.txt
    

    现在有了按键功能:

    def key_func(x):
            return os.path.split(x)[-1]
    for filename in sorted(glob.glob('[xy]/*.txt'), key=key_func):
            print filename
    # x/blub01.txt
    # x/blub02.txt
    # x/blub03.txt
    # y/blub05.txt
    # x/blub10.txt
    

    编辑: 可能这个关键功能可以对您的文件进行排序:

    pat=re.compile("(\d+)\D*$")
    ...
    def key_func(x):
            mat=pat.search(os.path.split(x)[-1]) # match last group of digits
            if mat is None:
                return x
            return "{:>10}".format(mat.group(1)) # right align to 10 digits.
    

    当然可以改进,但我想你明白了。没有数字的路径将被单独保留,有数字的路径将被转换为一个 10 位宽并包含数字的字符串。

    【讨论】:

    • 不幸的是sorted函数没有改变顺序。
    • 它确实 -- y/blub05.txt 从最后一个位置向上移动,因为 blub05.txtblub10.txt 之前。只比较文件名,不比较key_func中的目录。
    • 其实我的文件没有零。它们被重命名为 x/blub1.txt x/blub2.txt x/blub10​​.txt,这会产生错误的顺序,即使使用 sort 命令也是如此。 x/blub3.txt y/blub5.txt
    • 当排序字符串 '1' 在 '9' 之前,这就是你看到这种行为的原因。您可以根据我的回答更改 key_func 以隔离该数字。
    【解决方案3】:
    glob.glob(os.path.join( '*.txt'))
    

    返回一个字符串列表,因此您可以使用 pythons sorted() function 轻松对列表进行排序。

    sorted(glob.glob(os.path.join( '*.txt')))
    

    【讨论】:

    • 排序函数给出相同的结果 当前正在处理的文件是:file10.txt.txt 当前正在处理的文件是:file11.txt.txt 当前正在处理的文件是:file9.txt.txt
    【解决方案4】:

    您需要通过隔离文件名中的数字来将排序从“ASCIIBetical”更改为数字。你可以这样做:

    import re
    
    def keyFunc(afilename):
        nondigits = re.compile("\D")
        return int(nondigits.sub("", afilename))
    
    filenames = ["file10.txt", "file11.txt", "file9.txt"]
    
    for x in sorted(filenames, key=keyFunc):
       print xcode here
    

    您可以在哪里使用 glob.glob("*.txt"); 的结果设置文件名

    另外,keyFunc 函数假定文件名中包含一个数字,并且该数字仅在文件名中。您可以将该函数更改为尽可能复杂,以隔离您需要排序的数字。

    【讨论】:

    • 如果有不同名称的文件,用数字分组怎么办?前任。 foo1.txtfoo2.txt ..foo10.txt,然后是bar1.txtbar2.txt,等等?还是文件名中有两组数字?
    • @MartijnPieters:这不是原始问题的要求,我想你知道答案。 :)
    • 好吧,这个问题很可能使用了一小部分文件;事实证明,91011 序列是关键部分。我们不能假设我们在这里拥有全貌。 :-)
    • 同意大局。我假设提出问题的人可以根据需要将特定答案转换为更一般的答案。因此,我尝试给出一个最小但完整的答案(基于他们的问题),并希望他们能从那里取得成功。
    • 一般来说,我同意,但正则表达式并不总是有效:-)
    【解决方案5】:
    for fname in ['file9.txt','file10.txt','file11.txt']:
       with open(fname) as f: # default open mode is for reading
          for line in f:
             # do something with line
    

    【讨论】:

    • 其实我有几百个文件要处理,所以列出来很不方便。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多