os.path.commonprefix () e os.path.relpath () sono i tuoi amici:
>>> print os.path.commonprefix(['/usr/var/log', '/usr/var/security'])
'/usr/var'
>>> print os.path.commonprefix(['/tmp', '/usr/var']) # No common prefix: the root is the common prefix
'/'
È quindi possibile verificare se il prefisso comune è uno dei percorsi, ovvero se uno dei percorsi è un antenato comune:
paths = […, …, …]
common_prefix = os.path.commonprefix(list_of_paths)
if common_prefix in paths:
…
È quindi possibile trovare i percorsi relativi:
relative_paths = [os.path.relpath(path, common_prefix) for path in paths]
È anche possibile gestire più di due percorsi, con questo metodo, e verificare se tutti i percorsi sono tutti al di sotto di uno di essi.
PS : a seconda dell'aspetto dei tuoi percorsi, potresti voler prima eseguire un po 'di normalizzazione (questo è utile in situazioni in cui non si sa se finiscono sempre con' / 'o no, o se alcuni dei percorsi sono relativi). Le funzioni rilevanti includono os.path.abspath () e os.path.normpath () .
PPS : come menzionato da Peter Briggs nei commenti, il semplice approccio sopra descritto può fallire:
>>> os.path.commonprefix(['/usr/var', '/usr/var2/log'])
'/usr/var'
anche se non/usr/var è un prefisso comune dei percorsi. Forzare la fine di tutti i percorsi con '/' prima di chiamare risolve questo problema (specifico).commonprefix()
PPPS : come menzionato bluenote10, l'aggiunta di una barra non risolve il problema generale. Ecco la sua domanda di follow-up: Come eludere l'errore di os.path.commonprefix di Python?
PPPPS : a partire da Python 3.4, abbiamo pathlib , un modulo che fornisce un ambiente di manipolazione del percorso più igienico . Immagino che il prefisso comune di un insieme di percorsi possa essere ottenuto prendendo tutti i prefissi di ciascun percorso (con PurePath.parents()), prendendo l'intersezione di tutti questi insiemi principali e selezionando il prefisso comune più lungo.
PPPPPS : Python 3.5 ha introdotto una soluzione adeguata a questa domanda :,os.path.commonpath() che restituisce un percorso valido.