Reputation: 175
Suppose the following directory structure: -
|--apc
| |--data
| | |--datainstaller.zip
| | |--rs_details
| | | |--readme.txt
| |--rem
| | |--15.0.x
| | | |--15.0.1
| | | | |--dataconversion
| | | | | |--details.txt
| | | |--15.0.2
| | | | |--dataconversion
| | | | | |--details.txt
| | |--alloc_details.txt
| |--res
| | |--resapp.zip
|--REIM
| |--dataconversion
| | |--dataconversioninstaller.zip
| | |--rs_details.txt
| |--reim_bkp.zip
| |--hotfix
| | |--mergedRC
| | | |--alloc
| | | | |--p231.zip
|--testfile1.txt
|--testfile2.txt
is given as absolute paths (starting from the root directory and in a depth-first manner) in a python list as ( i.e., the paths are given as strings in a list) :-
['apc/','apc/data/', 'apc/data/datainstaller.zip', 'apc/data/rs_details/', 'apc/data/rs_details/readme.txt', 'apc/rem/', 'apc/rem/15.0.x/', 'apc/rem/15.0.x/15.0.1/', 'apc/rem/15.0.x/15.0.1/dataconversion/', 'apc/rem/15.0.x/15.0.1/dataconversion/details.txt', 'apc/rem/15.0.x/15.0.2/', 'apc/rem/15.0.x/15.0.2/dataconversion/', 'apc/rem/15.0.x/15.0.2/dataconversion/details.txt', 'apc/rem/alloc_details.txt', 'apc/res/', 'apc/res/resapp.zip', 'REIM/', 'REIM/dataconversion/', 'REIM/dataconversion/dataconversioninstaller.zip', 'REIM/dataconversion/rs_details.txt', 'REIM/reim_bkp.zip', 'REIM/hotfix/', 'REIM/hotfix/mergedRC/', 'REIM/hotfix/mergedRC/alloc', 'REIM/hotfix/mergedRC/alloc/p231.zip', 'testfile1.txt', 'testfile2.txt']
I want to create a nested dictionary to store this directory structure which would be something like this :-
{
'apc/': {
'apc/data/':{
'apc/data/datainstaller.zip' : {}
'apc/data/rs_details/' : {
'apc/data/rs_details/readme.txt' : {}
}
'apc/rem/':{
'apc/rem/15.0.x' : {
'apc/rem/15.0.x/15.0.1/': {
'apc/rem/15.0.x/15.0.1/dataconversion' : { 'apc/rem/15.0.x/15.0.1/dataconversion/details.txt' : {} }
}
'apc/rem/15.0.x/15.0.2/': {
'apc/rem/15.0.x/15.0.2/dataconversion' : { 'apc/rem/15.0.x/15.0.2/dataconversion/details.txt' : {} }
}
}
}
}
}
I tried to do it iteratively as well as recursively too by using the parameter as number of /
in the path and finding prefix in the lower level directory paths but it resulted in an inconsistent nested dictionary and I could not get the desired one as shown above.
Can anyone help me out with this?
[Edit: The path string of directories always end with a /
whereas the path string of files do not]
Upvotes: 0
Views: 617
Reputation: 481
This would do it:
import os, json
directory_dict = {}
path_list = ['apc/','apc/data/', 'apc/data/datainstaller.zip', 'apc/data/rs_details/', 'apc/data/rs_details/readme.txt', 'apc/rem/', 'apc/rem/15.0.x/', 'apc/rem/15.0.x/15.0.1/', 'apc/rem/15.0.x/15.0.1/dataconversion/', 'apc/rem/15.0.x/15.0.1/dataconversion/details.txt', 'apc/rem/15.0.x/15.0.2/', 'apc/rem/15.0.x/15.0.2/dataconversion/', 'apc/rem/15.0.x/15.0.2/dataconversion/details.txt', 'apc/rem/alloc_details.txt', 'apc/res/', 'apc/res/resapp.zip', 'REIM/', 'REIM/dataconversion/', 'REIM/dataconversion/dataconversioninstaller.zip', 'REIM/dataconversion/rs_details.txt', 'REIM/reim_bkp.zip', 'REIM/hotfix/', 'REIM/hotfix/mergedRC/', 'REIM/hotfix/mergedRC/alloc', 'REIM/hotfix/mergedRC/alloc/p231.zip', 'testfile1.txt', 'testfile2.txt']
for item in path_list:
path, filename = os.path.split(item)
split_path = path.split('/')
# directory_level is a pointer into the directory_dict
directory_level = directory_dict
# current_directory is a string to hold the path name as we build it up again from iterating the split_path list
current_directory = ''
for path_item in split_path:
# build up the current_directory
current_directory += path_item + '/'
if current_directory not in directory_level:
# insert new dictionary at this level
directory_level[current_directory] = {}
# set the directory_level pointer to new level
directory_level = directory_level[current_directory]
if filename:
# add the whole item into the dictionary at this level
directory_level[item] = {}
print(json.dumps(directory_dict, indent=4))
And the output:
{
"apc/": {
"apc/data/": {
"apc/data/datainstaller.zip": {},
"apc/data/rs_details/": {
"apc/data/rs_details/readme.txt": {}
}
},
"apc/rem/": {
"apc/rem/15.0.x/": {
"apc/rem/15.0.x/15.0.1/": {
"apc/rem/15.0.x/15.0.1/dataconversion/": {
"apc/rem/15.0.x/15.0.1/dataconversion/details.txt": {}
}
},
"apc/rem/15.0.x/15.0.2/": {
"apc/rem/15.0.x/15.0.2/dataconversion/": {
"apc/rem/15.0.x/15.0.2/dataconversion/details.txt": {}
}
}
},
"apc/rem/alloc_details.txt": {}
},
"apc/res/": {
"apc/res/resapp.zip": {}
}
},
"REIM/": {
"REIM/dataconversion/": {
"REIM/dataconversion/dataconversioninstaller.zip": {},
"REIM/dataconversion/rs_details.txt": {}
},
"REIM/reim_bkp.zip": {},
"REIM/hotfix/": {
"REIM/hotfix/mergedRC/": {
"REIM/hotfix/mergedRC/alloc": {},
"REIM/hotfix/mergedRC/alloc/": {
"REIM/hotfix/mergedRC/alloc/p231.zip": {}
}
}
}
},
"/": {
"testfile1.txt": {},
"testfile2.txt": {}
}
}
Upvotes: 1