2009-12-10 6 views
0

Привет всем, это мой первый раз, недавно пытавшийся попасть в файл и часть Python. Я пытаюсь найти каталог, а затем найти все подкаталоги. Если в каталоге нет папок, добавьте все файлы в список. И организуйте их все по диктову.Поиск и организация каталогов Python с помощью dict

Так, например, дерево может выглядеть следующим образом

  • Начиная Путь
    • Dir 1
      • SUBDIR 1
      • SUBDIR 2
      • SUBDIR 3
        • subsubdir
          • file.jpg
          • папка1
            • file1.jpg
            • file2.jpg
          • folder2
            • file3.jpg
            • file4.jpg

Даже если subsubdir есть файл в нем, он должен быть пропущен, поскольку он имеет папки в нем.

Теперь я могу нормально это сделать, если знаю, сколько каталогов я ищу, используя os.listdir и os.path.isdir. Однако, если я хочу, чтобы это было динамическим, оно должно было бы компенсировать любое количество папок и подпапок. Я пробовал использовать os.walk, и он найдет все файлы легко. Единственная проблема, с которой я столкнулась, - создать все dicts с именами путей, которые содержат файл. Мне нужны имена папок, организованные dict, вплоть до начального пути.

Таким образом, в конце концов, используя пример выше, ДИКТ должен выглядеть следующим образом с файлами в нем:

dict['dir1']['subdir3']['subsubdir']['folder1'] = ['file1.jpg', 'file2.jpg'] 

dict['dir1']['subdir3']['subsubdir']['folder2'] = ['file3.jpg', 'file4.jpg'] 

бы признателен за любую помощь в этом или лучшие идеи по организации информации. Благодарю.

+0

для чего вы собираетесь использовать дерево каталогов? – u0b34a0f6ae

ответ

1

Существует основная проблема с тем, как вы хотите структурировать данные. Если dir1/subdir1 содержит подкаталоги и файлы, следует ли dict['dir1']['subdir1'] быть списком или словарем? Чтобы получить доступ к дополнительным подкаталогам с помощью ...['subdir2'], это должен быть словарь, но с другой стороны dict['dir1']['subdir1'] должен возвращать список файлов.

Либо вы должны построить дерево из пользовательских объектов, которые каким-либо образом сочетают эти два аспекта, или вам придется изменить древовидную структуру для обработки файлов по-разному.

+0

Ну вот почему я так хочу, если он найдет папку, он просто пропустит добавление файлов. – Chuck

1

Я не знаю, почему вы хотели бы это сделать. Вы должны быть в состоянии сделать вашу обработку с помощью os.path.walk, но в случае, если вам действительно нужна такая структура, вы можете сделать (непроверенные):

import os 

def dirfunc(fdict, dirname, fnames): 
    tmpdict = fdict 
    keys = dirname.split(os.sep)[:-1] 
    for k in keys: 
     tmpdict = tmpdict.setdefault(k, {}) 

    for f in fnames: 
     if os.path.isdir(f): 
      return 

    tmpdict[dirname] = fnames 

mydict = {} 
os.walk(directory_to_search, dirfunc, mydict) 

Кроме того, вы не должны назвать свою переменную dict, потому что это Python встроенная в. Это очень плохой идеей, чтобы переустановить имя dict на что-то другое, кроме типа dict Python.

Редактировать: отредактировано, чтобы исправить ошибку «двойной последний ключ» и использовать os.walk.

+0

Да. Переменная dict была только мне ленивой. В любом случае это работает, за исключением того, что создает дубликат ключа, если есть файл. Другими словами (используя приведенный выше пример) dictvar ['dir1'] ['subdir3'] ['subsubdir'] ['folder2'] ['folder2'] = ['file3.jpg', 'file4.jpg' ] – Chuck

+0

Это опасность при вставке непроверенного кода. Вы можете исправить это, выполнив: keys = dirname.split (os.sep) [: - 1]. –

+0

использовать os.walk(), а не os.path.walk – ghostdog74

3

Может быть, вы хотите что-то вроде:

def explore(starting_path): 
    alld = {'': {}} 

    for dirpath, dirnames, filenames in os.walk(starting_path): 
    d = alld 
    dirpath = dirpath[len(starting_path):] 
    for subd in dirpath.split(os.sep): 
     based = d 
     d = d[subd] 
    if dirnames: 
     for dn in dirnames: 
     d[dn] = {} 
    else: 
     based[subd] = filenames 
    return alld[''] 

К примеру, учитывая /tmp/a, что:

$ ls -FR /tmp/a 
b/ c/ d/ 

/tmp/a/b: 
z/ 

/tmp/a/b/z: 

/tmp/a/c: 
za zu 

/tmp/a/d: 

print explore('/tmp/a') излучает: {'c': ['za', 'zu'], 'b': {'z': []}, 'd': []}.

Если это не совсем то, что вам нужно, может быть, вы можете показать нам, какие именно различия должны быть? Я подозреваю, что они, вероятно, могут быть легко исправлены, если потребуется.

+1

К сожалению, это вызывает KeyErrors, поэтому я не могу это проверить. Однако из возвращаемого dict в вашем примере звучит правильно. – Chuck

+0

Это было самое близкое ясное решение моей очень похожей проблемы. Благодарю. – tatlar