2015-04-24 10 views
8

Diciamo che ho due nomi di percorso: capo e coda. Possono sovrapporsi con qualsiasi numero di segmenti. Se non lo fanno, mi piacerebbe unirmi a loro normalmente. Se si sovrappongono, mi piacerebbe rilevare la parte comune e combinarli di conseguenza. Per essere più specifici: se ci sono ripetizioni nei nomi mi piacerebbe trovare la parte più lunga sovrapposizione possibile. EsempioC'è un modo intelligente per combinare percorsi sovrapposti in python?

"/root/d1/d2/d1/d2" + "d2/d1/d2/file.txt" == "/root/d1/d2/d1/d2/file.txt" 
and not "/root/d1/d2/d1/d2/d1/d2/file.txt" 

Esiste una funzione di libreria pronta per l'uso per tale caso o devo implementarne una?

+0

È in Django? O solo pitone? – WakeskaterX

+0

Questi percorsi si troveranno sulla stessa macchina su cui è in esecuzione il codice? – Rcynic

+0

si avvia sempre su/root? quale dovrebbe essere il risultato se entrambi sono 'd1/d2'? – miraculixx

risposta

3

È possibile utilizzare un elenco di comprensione all'interno join funzione:

>>> p1="/root/d1/d2/d1/d2" 
>>> p2="d2/d1/d2/file.txt" 
>>> p1+'/'+'/'.join([i for i in p2.split('/') if i not in p1.split('/')]) 
'/root/d1/d2/d1/d2/file.txt' 

O se la differenza è solo il nome base del secondo percorso è possibile utilizzare os.path.basename per ottenere il bname e concatenare a p1:

>>> import os 
>>> p1+'/'+os.path.basename(p2) 
'/root/d1/d2/d1/d2/file.txt' 
+0

Works! Sei un genio! – ardabro

+0

@ardabro Benvenuto! ;) – Kasramvd

+2

L'uso di 'os.sep' potrebbe funzionare per separatori diversi –

3

vorrei suggerire di utilizzare difflib.SequenceMatcher seguita da get_matching_blocks

>>> p1, p2 = "/root/d1/d2/d1/d2","d2/d1/d2/file.txt" 
>>> sm = difflib.SequenceMatcher(None,p1, p2) 
>>> size = sm.get_matching_blocks()[0].size 
>>> path = p1 + p2[size:] 
>>> path 
'/root/d1/d2/d1/d2/file.txt' 

Ans una soluzione generale

def join_overlapping_path(p1, p2): 
    sm = difflib.SequenceMatcher(None,p1, p2) 
    p1i, p2i, size = sm.get_matching_blocks()[0] 
    if not p1i or not p2i: None 
    p1, p2 = (p1, p2) if p2i == 0 else (p2, p1) 
    size = sm.get_matching_blocks()[0].size 
    return p1 + p2[size:] 

Esecuzione

>>> join_overlapping_path(p1, p2) 
'/root/d1/d2/d1/d2/file.txt' 
>>> join_overlapping_path(p2, p1) 
'/root/d1/d2/d1/d2/file.txt' 
1

Penso che questo funziona:

p1 = "/root/d1/d2/d1/d2" 
p2 = "d2/d1/d2/file.txt" 

def find_joined_path(p1, p2): 
    for i in range(len(p1)): 
     if p1[i:] == p2[:len(p1) - i]: 
      return p1[:i] + p2 

print(find_joined_path(p1, p2)) 

Si noti che si tratta di una soluzione generale che funziona per ogni due stringhe, in modo da potrebbe non essere ottimizzato come una soluzione che funziona solo con i percorsi dei file.

Problemi correlati