Reputation: 175
I am given a list of list of absolute directory paths in a list as:-
[ ['19.2.000/'],['19.2.000/data/'],
['19.2.000/data/datainstaller.zip'], ['19.2.000/data/rs_details'],
['19.2.000/rem/'],
['19.2.000/rem/remapp.zip'], ['19.2.000/rem/rs_details'],
['19.2.000/res/'], ['19.2.000/res/resapp.zip'], ['19.2.000/rms/'],
['19.2.000/rms/BdiEdge.zip'], ['19.2.001/'],
['19.2.001/dataconversion/'],
['19.2.001/dataconversion/dataconversioninstaller.zip'],
['19.2.001/dataconversion/rs_details'] ]
And I want to display the directory structure as:-
|--19.2.000
| |--data
| | |--datainstaller.zip
| | |--rs_details
| |--rem
| | |--remapp.zip
| | |--rs_details
| |--res
| | |--resapp.zip
| |--rms
| | |--BdiEdge.zip
|--19.2.001
| |--dataconversion
| | |--dataconversioninstaller.zip
| | |--rs_details
I tried to do it with nested for loops (by storing each level in a different lists) but with increasing levels of directory, it becomes redundant and slow. Any other way to optimally display it?
Upvotes: 2
Views: 150
Reputation: 664
I'd start by sorting the lists- then they are in the order you want at least. This was extrapolated out to use vars for the indents based on num '/' and what index of the split on '/' gets used.
This problem caught my interest to be honest, so here is a version that should work with any dir structure you supply as a list, even if some of the sub-folders are not listed.
def make_fldr(arr):
print("-- Processing Pass 1 --")
processed = []
path_repr = ''
sub_dir = '| '
for path in arr:
dirs = path[0].split("/")
num_slash = path[0].count('/')
sep = '/'
for i in range(num_slash):
rep = sep.join(dirs[:i+1])
if [rep+'/'] not in arr:
arr.append([rep+'/'])
[processed.append(x) for x in arr if x not in processed]
print("-- Building structure: Pass 2 --")
processed.sort()
print("Processed List is sorted")
for path in processed:
num_slash = path[0].count('/')
if num_slash == 1:
piece = path[0].split("/")
if piece[1] == '':
path_repr += f'|--{piece[0]}\n'
else:
path_repr += f'{sub_dir}|--{piece[1]}\n'
else:
if path[0].split("/")[-1] == '':
path_repr += f'{sub_dir * (num_slash-1)}|--{path[0].split("/")[-2]}\n'
else:
path_repr += f'{sub_dir * num_slash}|--{path[0].split("/")[-1]}\n'
return path_repr
structure = make_fldr(data)
print(structure)
Given an expanded set
data = [
['19.2.000/'],
['19.2.000/resa/'],
['19.2.000/resa/resa19application.zip'],
['19.2.000/rms/'],
['19.2.000/rms/BdiEdgeAppJobAdminPak19.1.000ForRms19.1.000_eng_ga.zip'],
['19.2.001/'],
['19.2/'],
['19.2/rpm/'],
['19.2/rpm/release_details'],
['19.2/rpm/rpm19application.zip'],
['RESA/'],
['RESA/folder1/'],
['RESA/folder1/release_details'],
['RESA/folder1/resainstaller.zip'],
['RESA/release_details'],
['RESA/resainstaller.zip'],
['RMS/'],
['RMS/release_details'],
['RMS/rmsinstaller.zip'],
['RPM/'],
['RPM/release_details'],
['RPM/rpminstaller.zip']
]
the function above yields
Processed List is sorted
|--19.2.000
| |--resa
| | |--resa19application.zip
| |--rms
| | |--BdiEdgeAppJobAdminPak19.1.000ForRms19.1.000_eng_ga.zip
|--19.2.001
|--19.2
| |--rpm
| | |--release_details
| | |--rpm19application.zip
|--RESA
| |--folder1
| | |--release_details
| | |--resainstaller.zip
| |--release_details
| |--resainstaller.zip
|--RMS
| |--release_details
| |--rmsinstaller.zip
|--RPM
| |--release_details
| |--rpminstaller.zip
I tested with the complete file you shared- it seems to work ok. The reason the earlier version did not work was that I'd assumed all sub-dirs ended with a '/', but some did not. Once I tested with the complete set I could work out where the error was happening.
Upvotes: 2