Simplify Path in Python

In Unix-style file systems, we often need to simplify absolute file paths to their canonical form. A canonical path is the shortest string representing the absolute path, following specific rules for directory navigation.

Canonical Path Rules

  • Path must always begin with a slash /
  • There must be only a single slash / between two directory names
  • Last directory name (if it exists) must not end with a trailing /
  • Single period . refers to the current directory
  • Double period .. moves up one level to the parent directory

For example, "/home/", "/../" and "/home//user/" should be simplified to "/home", "/", and "/home/user" respectively.

Algorithm

We can solve this using a stack-based approach ?

  1. Initialize a stack with '/'
  2. Split the path by '/' delimiter
  3. For each component:
    • If ".." - pop from stack (go to parent directory)
    • If "." or empty string - ignore
    • Otherwise - push the directory to stack
  4. Join all stack elements to form the canonical path

Implementation

class Solution:
    def simplifyPath(self, path):
        stack = ['/']
        components = path.split("/")
        
        for component in components:
            if component == '..':
                # Go to parent directory
                if len(stack) > 1:
                    stack.pop()
                else:
                    continue
            elif component == '.' or component == '':
                # Current directory or empty - ignore
                continue
            else:
                # Valid directory name
                stack.append("/" + component)
        
        # If only root remains
        if len(stack) == 1:
            return "/"
        
        # Join all path components (skip the first '/')
        return "".join(stack[1:])

# Test the solution
solution = Solution()
print(solution.simplifyPath("/home/"))
print(solution.simplifyPath("/../"))
print(solution.simplifyPath("/home//user/"))
print(solution.simplifyPath("/a/./b/../../c/"))
/home
/
/home/user
/c

How It Works

Let's trace through "/home//user/" ?

  1. Split by '/': ['', 'home', '', 'user', '']
  2. Process each component:
    • '' (empty) - ignore
    • 'home' - add '/home' to stack: ['/', '/home']
    • '' (empty) - ignore
    • 'user' - add '/user' to stack: ['/', '/home', '/user']
    • '' (empty) - ignore
  3. Join components (skip first '/'): "/home/user"

Alternative Approach

Using Python's built-in os.path.normpath() for comparison ?

import os

paths = ["/home/", "/../", "/home//user/", "/a/./b/../../c/"]

for path in paths:
    normalized = os.path.normpath(path)
    # Ensure it starts with '/' for absolute paths
    if not normalized.startswith('/'):
        normalized = '/' + normalized
    print(f"{path} -> {normalized}")
/home/ -> /home
/../ -> /
/home//user/ -> /home/user
/a/./b/../../c/ -> /c

Conclusion

The stack-based approach efficiently simplifies Unix paths by processing each directory component. This method handles all edge cases including parent directory navigation and redundant separators, producing clean canonical paths.

Updated on: 2026-03-25T07:56:23+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements