views:

91

answers:

3

Hey,

I got a list of paths and I need to extract the first element of each path in a portable way, how would I do that?

['/abs/path/foo',
 'rel/path',
 'just-a-file']

to

['abs', 'rel', 'just-a-file']

Thanks in advance Oli

+3  A: 
In [69]: import os

In [70]: paths
Out[70]: ['/abs/path/foo', 'rel/path', 'just-a-file']

In [71]: [next(part for part in path.split(os.path.sep) if part) for path in paths]
Out[71]: ['abs', 'rel', 'just-a-file']
unutbu
Thats not portable, consider a path like "C:\Users\foo" which should result in "Users", but with your solution it wont.
b52
If you want to get rid of the drives, call `os.path.splitdrive(p)[1]` on each of the paths beforehand. (BTW, you never specified what you wanted done in the case of drive letters in the original post. Don't expect us to read your mind.)
Tim Yates
+1  A: 

There is a library call to handle splitting paths in a platform independent way but it only splits into two parts:

import os.path

def paths(p) :
  head,tail = os.path.split(p)
  components = []
  while len(tail)>0:
    components.insert(0,tail)
    head,tail = os.path.split(head)
  return components

for p in ['/abs/path/foo','rel/path','just-a-file'] :
  print paths(p)[0]
Amoss
A: 

Why not just use a regex?

>>> import re
>>> paths = ['/abs/path/foo',
...          'rel/path',
...          'just-a-file']
>>> 
>>> [re.match(r'\/?([^\/]+)', p).groups()[0] for p in paths]
['abs', 'rel', 'just-a-file']

and for Windows:

>>> paths = [r'\abs\path\foo',
...          r'rel\path',
...          r'just-a-file',
...          r'C:\abs\path\foo',
...          r'C:rel\path',
...          r'C:just-a-file']
>>> 
>>> [re.match(r'(?:[A-Za-z]:)?\\?([^\\]+)', p).groups()[0] for p in paths]
['abs', 'rel', 'just-a-file', 'abs', 'rel', 'just-a-file']
ma3