You can use os.sep
just
import os
path_string.split(os.sep)
For more info, look the doc
Answer from atupal on Stack Overflowos.path.join(path1[, path2[, ...]]) Join one or more path components intelligently. If any component is an absolute path, all previous components (on Windows, including the previous drive letter, if there was one) are thrown away, and joining continues. The return value is the concatenation of path1, and optionally path2, etc., with exactly one directory separator (os.sep) following each non-empty part except the last. (This means that an empty last part will result in a path that ends with a separator.) Note that on Windows, since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\foo.
You can use os.sep
just
import os
path_string.split(os.sep)
For more info, look the doc
os.path.join(path1[, path2[, ...]]) Join one or more path components intelligently. If any component is an absolute path, all previous components (on Windows, including the previous drive letter, if there was one) are thrown away, and joining continues. The return value is the concatenation of path1, and optionally path2, etc., with exactly one directory separator (os.sep) following each non-empty part except the last. (This means that an empty last part will result in a path that ends with a separator.) Note that on Windows, since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\foo.
Use os.path.split. It is a system independent way to split paths. Note that this only splits into (head, tail). To get all the individual parts, you need to recursively split head or use str.split using os.path.sep as the separator.
Split path in Python - Stack Overflow
cross-platform splitting of path in python - Stack Overflow
Slash vs backslash to separate folders
Standard python function to split paths? - Stack Overflow
python 3.4 has methods for that (note the forward slashes instead of the backslashes (or double the backslashes))
pathlib documentation
# python 3.4
from pathlib import Path
p = Path('C:/my_dir/repo/branch')
print(p.parent)
print(p.name)
for what you need parts is interesting:
print(p.parts)
# -> ('C:', 'my_dir', 'repo', 'branch')
print('\\'.join(p.parts[:2]), ' -- ', '\\'.join( p.parts[2:]))
# -> C:\my_dir -- repo\branch
in python 2.7 this needs a bit more work:
import os
p = 'C:/my_dir/repo/branch'
def split_path(path):
parts = []
while 1:
path, folder = os.path.split(path)
if folder:
parts.append(folder)
else:
if path:
parts.append(path)
break
parts.reverse()
return parts
parts = split_path(p)
print('\\'.join(parts[:2]), ' -- ', '\\'.join(parts[2:]))
# -> C:\my_dir -- repo\branch
Using regular expression (re module documentation):
>>> import re
>>> print(re.match(r'[^\\]+\\[^\\]+', r'C:\my_dir\repo\branch').group())
C:\my_dir
>>> re.findall(r'[^\\]+\\[^\\]+|.+', r'C:\my_dir\repo\branch')
['C:\\my_dir', '\\repo\\branch']
Python 3.4 introduced a new module pathlib. pathlib.Path provides file system related methods, while pathlib.PurePath operates completely independent of the file system:
>>> from pathlib import PurePath
>>> path = "/foo/bar/baz/file"
>>> path_split = PurePath(path).parts
>>> path_split
('\\', 'foo', 'bar', 'baz', 'file')
You can use PosixPath and WindowsPath explicitly when desired:
>>> from pathlib import PureWindowsPath, PurePosixPath
>>> PureWindowsPath(path).parts
('\\', 'foo', 'bar', 'baz', 'file')
>>> PurePosixPath(path).parts
('/', 'foo', 'bar', 'baz', 'file')
And of course, it works with Windows paths as well:
>>> wpath = r"C:\foo\bar\baz\file"
>>> PurePath(wpath).parts
('C:\\', 'foo', 'bar', 'baz', 'file')
>>> PureWindowsPath(wpath).parts
('C:\\', 'foo', 'bar', 'baz', 'file')
>>> PurePosixPath(wpath).parts
('C:\\foo\\bar\\baz\\file',)
>>>
>>> wpath = r"C:\foo/bar/baz/file"
>>> PurePath(wpath).parts
('C:\\', 'foo', 'bar', 'baz', 'file')
>>> PureWindowsPath(wpath).parts
('C:\\', 'foo', 'bar', 'baz', 'file')
>>> PurePosixPath(wpath).parts
('C:\\foo', 'bar', 'baz', 'file')
Huzzah for Python devs constantly improving the language!
The OP specified "will work with Windows paths too". There are a few wrinkles with Windows paths.
Firstly, Windows has the concept of multiple drives, each with its own current working directory, and 'c:foo' and 'c:\\foo' are often not the same. Consequently it is a very good idea to separate out any drive designator first, using os.path.splitdrive(). Then reassembling the path (if required) can be done correctly by
drive + os.path.join(*other_pieces)
Secondly, Windows paths can contain slashes or backslashes or a mixture. Consequently, using os.sep when parsing an unnormalised path is not useful.
More generally:
The results produced for 'foo' and 'foo/' should not be identical.
The loop termination condition seems to be best expressed as "os.path.split() treated its input as unsplittable".
Here's a suggested solution, with tests, including a comparison with @Spacedman's solution
import os.path
def os_path_split_asunder(path, debug=False):
parts = []
while True:
newpath, tail = os.path.split(path)
if debug: print repr(path), (newpath, tail)
if newpath == path:
assert not tail
if path: parts.append(path)
break
parts.append(tail)
path = newpath
parts.reverse()
return parts
def spacedman_parts(path):
components = []
while True:
(path,tail) = os.path.split(path)
if not tail:
return components
components.insert(0,tail)
if __name__ == "__main__":
tests = [
'',
'foo',
'foo/',
'foo\\',
'/foo',
'\\foo',
'foo/bar',
'/',
'c:',
'c:/',
'c:foo',
'c:/foo',
'c:/users/john/foo.txt',
'/users/john/foo.txt',
'foo/bar/baz/loop',
'foo/bar/baz/',
'//hostname/foo/bar.txt',
]
for i, test in enumerate(tests):
print "\nTest %d: %r" % (i, test)
drive, path = os.path.splitdrive(test)
print 'drive, path', repr(drive), repr(path)
a = os_path_split_asunder(path)
b = spacedman_parts(path)
print "a ... %r" % a
print "b ... %r" % b
print a == b
and here's the output (Python 2.7.1, Windows 7 Pro):
Test 0: ''
drive, path '' ''
a ... []
b ... []
True
Test 1: 'foo'
drive, path '' 'foo'
a ... ['foo']
b ... ['foo']
True
Test 2: 'foo/'
drive, path '' 'foo/'
a ... ['foo', '']
b ... []
False
Test 3: 'foo\\'
drive, path '' 'foo\\'
a ... ['foo', '']
b ... []
False
Test 4: '/foo'
drive, path '' '/foo'
a ... ['/', 'foo']
b ... ['foo']
False
Test 5: '\\foo'
drive, path '' '\\foo'
a ... ['\\', 'foo']
b ... ['foo']
False
Test 6: 'foo/bar'
drive, path '' 'foo/bar'
a ... ['foo', 'bar']
b ... ['foo', 'bar']
True
Test 7: '/'
drive, path '' '/'
a ... ['/']
b ... []
False
Test 8: 'c:'
drive, path 'c:' ''
a ... []
b ... []
True
Test 9: 'c:/'
drive, path 'c:' '/'
a ... ['/']
b ... []
False
Test 10: 'c:foo'
drive, path 'c:' 'foo'
a ... ['foo']
b ... ['foo']
True
Test 11: 'c:/foo'
drive, path 'c:' '/foo'
a ... ['/', 'foo']
b ... ['foo']
False
Test 12: 'c:/users/john/foo.txt'
drive, path 'c:' '/users/john/foo.txt'
a ... ['/', 'users', 'john', 'foo.txt']
b ... ['users', 'john', 'foo.txt']
False
Test 13: '/users/john/foo.txt'
drive, path '' '/users/john/foo.txt'
a ... ['/', 'users', 'john', 'foo.txt']
b ... ['users', 'john', 'foo.txt']
False
Test 14: 'foo/bar/baz/loop'
drive, path '' 'foo/bar/baz/loop'
a ... ['foo', 'bar', 'baz', 'loop']
b ... ['foo', 'bar', 'baz', 'loop']
True
Test 15: 'foo/bar/baz/'
drive, path '' 'foo/bar/baz/'
a ... ['foo', 'bar', 'baz', '']
b ... []
False
Test 16: '//hostname/foo/bar.txt'
drive, path '' '//hostname/foo/bar.txt'
a ... ['//', 'hostname', 'foo', 'bar.txt']
b ... ['hostname', 'foo', 'bar.txt']
False
This may be a stupid question, but whenever I copy a file address in Windows it copies with the folders separated by backslashes, but when I want to open the folder in python, I have to change them all to standard slashes, is there a reason for this, such as a different meaning, or is it just that they use different naming conventions?
I'm obviously not an expert, so apologies in advance if I used the wrong terminology, thank you! :)
as close as you get (AFAIR) with the standard lib:
>>> import os
>>> help(os.path.split)
Help on function split in odule ntpath:
split(p)
Split a pathname.
Return tuple (head, tail) where tail is everything after the final slash.
Either part may be empty.
this does not solve your usecase, but is trivially to extend so it does. For more info, see the comments.
There's no single function that will do what you want...primarily because what you're asking doesn't make any sense from a path-manipulation standpoint (because discarding .. changes the path in a meaningful fashion).
You could do something along the lines of:
[x for x in path.split(os.path.sep) if x not in ['.', '..']]
Which gives you:
>>> path='/s//pam/../ham/./eggs'
>>> [x for x in path.split(os.path.sep) if x not in ['.', '..']]
['', 's', '', 'pam', 'ham', 'eggs']
And:
>>> path=r'C:\s\\pam\..\ham\.\eggs'
>>> [x for x in path.split(os.path.sep) if x not in ['.', '..']]
['C:', 's', '', 'pam', 'ham', 'eggs']
(As long as os.path.sep is \).
It's obviously not exactly what you're looking for, but maybe it points the way in the right direction.