2 votes

Comment stocker des chemins absolus et les afficher sous forme de structure de répertoire en python ?

On me donne une liste de chemins de répertoires absolus dans une liste comme:-

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

Et je veux afficher la structure du répertoire de la manière suivante :-

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

J'ai essayé de le faire avec des boucles for imbriquées (en stockant chaque niveau dans une liste différente) mais avec des niveaux croissants de répertoire, cela devient redondant et lent. Y a-t-il un autre moyen de l'afficher de manière optimale ?

1voto

srattigan Points 446

Je commencerais par trier les listes - elles seront alors dans l'ordre que vous voulez au moins. Ceci a été extrapolé pour utiliser des variables pour les indentations basées sur le num '/' et quel index de la division sur '/' est utilisé.

Pour être honnête, ce problème a suscité mon intérêt. Voici donc une version qui devrait fonctionner avec n'importe quelle structure de répertoire que vous fournissez comme liste, même si certains des sous-dossiers ne sont pas répertoriés.

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)

Étant donné un ensemble élargi

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

la fonction ci-dessus donne

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

J'ai testé avec le fichier complet que vous avez partagé - il semble fonctionner correctement. La raison pour laquelle la version précédente ne fonctionnait pas était que j'avais supposé que tous les sous-répertoires se terminaient par un '/', mais certains ne le faisaient pas. Une fois que j'ai testé avec le jeu complet, j'ai pu déterminer où l'erreur se produisait.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X