-1

I am trying to understand sys.path.

So I want to make code that returns directory tree like this,but I can't.

Can someone please tell me the code?

【sys.path】

['C:\\Users\\81802\\PycharmProjects\\PlayGround',

 'C:\\Users\\81802\\AppData\\Local\\Programs\\Python\\Python37\\python37.zip',

 'C:\\Users\\81802\\AppData\\Local\\Programs\\Python\\Python37\\DLLs',

 'C:\\Users\\81802\\AppData\\Local\\Programs\\Python\\Python37\\lib',

 'C:\\Users\\81802\\AppData\\Local\\Programs\\Python\\Python37',

 'C:\\Users\\81802\\PycharmProjects\\PlayGround\\venv',

 'C:\\Users\\81802\\PycharmProjects\\PlayGround\\venv\\lib\\site-packages',

 'C:\\Users\\81802\\PycharmProjects\\PlayGround\\venv\\lib\\site-packages\\setuptools-39.1.0-py3.7.egg',

 'C:\\Users\\81802\\PycharmProjects\\PlayGround\\venv\\lib\\site-packages\\pip-10.0.1-py3.7.egg']

【directory tree(dict)】

{'C:\\Users\\81802\\':
  [{'PycharmProjects\\PlayGround\\': 
      ['',
      {'venv\\': 
           ['',
           {'lib\\site-packages\\': 
                ['',
                'setuptools-39.1.0-py3.7.egg',
                 'pip-10.0.1-py3.7.egg']}]}]},
 {'AppData\\Local\\Programs\\Python\\Python37\\': 
      ['',
      'python37.zip',
      'DLLs',
      'lib']}]}
Psychotechnopath
  • 2,471
  • 5
  • 26
  • 47
pokio
  • 1
  • 2
  • What have you tried and didn't work? StackOverflow isn't for people writing code for you. Try writing it yourself and when you have problems you can't solve, post them to SO. – shevron Feb 24 '19 at 06:51
  • The method I'd use would be to build the full tree structure of arrays and dicts, without worrying about collapsing parts of the path like 'AppData\\Local\\Programs\\Python\\Python37\\'. Then, go back in and find entries with only one child in them and collapse those into the child's path, getting rid of that level of the tree. To build the initial structure, you'd iterate over all the paths, and for each path, process each level of the path by walking down the tree structure, creating dicts and arrays that don't yet exist. –  Feb 24 '19 at 07:12

2 Answers2

0

This will give you a dictionary where every key is a directory, and the values are lists of either file names or dictionaries with a subdirectory.

import os

def get_files_dict(startpath):
  tree = []  # this is the array of subdirectory objects
  for item in os.listdir(startpath):
    # we need to have a full path to the item in the directory
    item_path = os.path.join(startpath, item)
    if os.path.isfile(item_path):
      tree.append(item)
    else:
      # we call this function recursively for subdirectories
      tree.append(get_files_dict(item_path))
  return {os.path.basename(startpath):tree}

file_tree = get_files_dict(os.getcwd())

# this is just a helper function to print the tree nicely
def print_tree(d,i=0):
  for k,v in d.items():
    print("{}{}".format(" "*4*i, k+os.sep))
    for l in v:
      if type(l) is dict:
        print_tree(l,i+1)
      else:
        print("{}{}".format(" "*4*(i+1), l))

print_tree(file_tree)

And the printed output:

runner/
    .bashrc
    .bash_logout
    .profile
    .site-packages/
    main.py
    .config/
        pycodestyle
    _test_runner.py

This was inspired by this SO issue, but I changed quite a bit about the implementation.

0

This is the simplest I can get. The idea is to maintain a set of paths which didn't currently diverge.

import sys
from pprint import pprint
pprint(sys.path)

sep = '\\'

# check if all paths agree on the current name
def isSameName(paths, index):
    for path in paths:
        if index >= len(path) or path[index] != paths[0][index]:
            return False
    return True

#transform the current set of paths into tree
def toTree(paths, startIndex):
    index = startIndex
    if len(paths) == 1:
        return sep.join(paths[0][index:])
    while isSameName(paths, index):
        index += 1
    nameMap = dict()
    for path in paths:
        name = path[index] if len(path) > index else 0
        if not (name in nameMap):
            nameMap[name] = []
        nameMap[name].append(path)
    res = [toTree(paths, index) for paths in nameMap.values()]
    return { sep.join(paths[0][startIndex:index]) : res}

paths = [path.split(sep) for path in sys.path]
pprint(toTree(paths, 0))