Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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 ?
- Initialize a stack with
'/' - Split the path by
'/'delimiter - For each component:
- If
".."- pop from stack (go to parent directory) - If
"."or empty string - ignore - Otherwise - push the directory to stack
- If
- 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/" ?
- Split by
'/':['', 'home', '', 'user', ''] - Process each component:
-
''(empty) - ignore -
'home'- add'/home'to stack:['/', '/home'] -
''(empty) - ignore -
'user'- add'/user'to stack:['/', '/home', '/user'] -
''(empty) - ignore
-
- 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.
