Python: идентификация числовых имен папок в структуре папок - PullRequest
1 голос
/ 02 февраля 2020

У меня есть функция ниже, которая проходит по root данного каталога, захватывает все подкаталоги и помещает их в список. Эта часть работает, вроде.

Цель состоит в том, чтобы определить папку с наибольшим (наибольшим числом) числовым именем. Предполагая, что папка содержит только папки с числовыми именами и не содержит alphanumeri c папок с файлами, я хорошо Однако, если файл или папка не имеют числового имени, я сталкиваюсь с проблемами, потому что сценарий собирает все подкаталоги и файлы и загружает все в список.

Мне нужно просто найти те папки с именами цифр c и игнорировать все остальное.

Example folder structure for c:\Test
\20200202\
\20200109\
\20190308\
\Apples\
\Oranges\
New Document.txt

Это работает для обхода каталога, но помещает все в список, а не только подпапки Numberri c.

#Example code
import os 
from pprint import pprint 

files=[]
MAX_DEPTH = 1
folders = ['C:\\Test']
for stuff in folders:
    for root, dirs, files in os.walk(stuff, topdown=True):
        for subdirname in dirs:
            files.append(os.path.join(subdirname))
            #files.append(os.path.join(root, subdirname)) will give full directory
        #print("there are", len(files), "files in", root) will show counts of files per directory
        if root.count(os.sep) - stuff.count(os.sep) == MAX_DEPTH - 1:
            del dirs[:]
pprint(max(files))

Текущий результат max (файлы): Новый Document.txt

Желаемый вывод: 20200202

То, что я пробовал до сих пор:

Я пытался перехватить каждый элемент, прежде чем добавить его в список, чтобы посмотреть, можно ли преобразовать строку поддиректории. к int, а затем добавить его в список. Это не позволяет преобразовать подкаталоги namesri c в int, и каким-то образом (я не знаю, как) файл New Document.txt добавляется в список.

files=[]
    MAX_DEPTH = 1
    folders = ['C:\\Test']
    for stuff in folders:
        for root, dirs, files in os.walk(stuff, topdown=True):
            for subdirname in dirs:
                try:
                    subdirname = int(subdirname)
                    print("Found subdir named " + subdirname + " type: " + type(subdirname))
                    files.append(os.path.join(subdirname))
                except:
                    print("Error converting " + str(subdirname) + " to integer")
                    pass
                #files.append(os.path.join(root, subdirname)) will give full directory
            #print("there are", len(files), "files in", root) will show counts of files per directory
            if root.count(os.sep) - stuff.count(os.sep) == MAX_DEPTH - 1:
                del dirs[:]
    return (input + "/" + max(files))

Я также попытался добавить все в список, а затем создать второй список (ie, без попытки / кроме), используя приведенное ниже, но я получаю пустой список. Я не уверен, почему, и я не уверен, где / как начать искать. Использование 'type' в списке перед применением следующего показывает, что все в списке имеет тип str.

list2 = [x for x in files if isinstance(x,int) and not isinstance(x,bool)]

Ответы [ 2 ]

1 голос
/ 02 февраля 2020

Я иду на go вперед и отвечу на свой вопрос здесь:

Изменение метода полностью помогло, и сделало его значительно быстрее и проще.

#the find_newest_date function looks for a folder with the largest number and assumes that is the newest data
def find_newest_date(input):
    intlistfolders = []
    list_subfolders_with_paths = [f.name for f in os.scandir(input) if f.is_dir()]
    for x in list_subfolders_with_paths:
        try:
            intval = int(x)
            intlistfolders.append(intval)
        except:
            pass
    return (input + "/" + str(max(intlistfolders)))

Объяснение:

  • scandir в 3 раза быстрее, чем ходьба. производительность каталога
  • scandir также позволяет использовать f.name для извлечения только имен папок или f.path для получения путей.

Итак, используйте scandir для загрузки списка со всеми подкаталогами.

  1. Переберите список и попробуйте преобразовать каждое значение в целое число. Я не знаю, почему это не сработает в предыдущем примере, но работает в этом случае.
  2. Первая часть оператора try преобразуется в целое число.
  3. Если преобразование завершается неудачно, выполняется условие исключение, а «pass» по существу является пустым оператором. Он ничего не делает.
  4. Затем, наконец, объедините входной каталог со строковым представлением максимального значения цифры c (ie самая последняя из датированных папок в данном случае).

Функция вызывается с помощью:

folder_named_path = find_newest_date("C:\\Test") or something similar. 
0 голосов
/ 02 февраля 2020

Попробуйте сопоставить dirs с регулярным выражением. num = r”[0-9]+” - это ваше регулярное выражение. Что-то вроде re.findall(num,subdirname) возвращает вам совпадающую строку, состоящую из одного или нескольких чисел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...