Подтвердить что ты не робот

Чтение файлов в определенном порядке в python

Допустим, у меня есть три файла в папке: 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

и он считывает первый файл10.txt, затем файл11.txt, а затем файл9.txt.

Может кто-нибудь помочь мне, как получить правильный заказ?

4b9b3361

Ответ 1

Файлы в файловой системе не сортируются. Вы можете отсортировать полученные имена файлов самостоятельно, используя функцию sorted():

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']

Ответ 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

EDIT: Возможно, эта ключевая функция может сортировать ваши файлы:

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 цифр и содержать номер.

Ответ 3

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

возвращает список строк, поэтому вы можете легко отсортировать список с помощью pythons sorted() function.

sorted(glob.glob(os.path.join( '*.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 предполагает, что имя файла будет содержать номер в нем, а число будет только в имени файла. Вы можете изменить эту функцию как сложную, так как вам нужно выделить число, необходимое для сортировки.

Ответ 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