Problem
You need to know the relative path from one directory to anotherfor example, to create a symbolic link or a relative reference in a URL.
Solution
Precondition
itertools.izip(*iterables)
Make an iterator that aggregates elements from each of the iterables. Like zip()except that it returns an iterator instead of a list. Used for lock-step iteration over several iterables at a time.
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
itertools.izip
1
>>> import itertools
2
>>> s1='/a/b/c/d'
3
>>> s2='/a/b/c1/d1'
4
>>> t1=s1.split('/')
5
>>> t2=s2.split('/')
6
>>> t1
7
['', 'a', 'b', 'c', 'd']
8
>>> t2
9
['', 'a', 'b', 'c1', 'd1']
10
>>> test = itertools.izip(t1, t2)
11
>>> for s in test:
12
print s
13
('', '')
14
('a', 'a')
15
('b', 'b')
16
('c', 'c1')
17
('d', 'd1')
Code
all_equal: return True if all the elements are equal, otherwise False.
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
all_equal
1
>>> def all_equal(elements):
2
first = elements[0]
3
for e in elements[1:]:
4
if first != e:
5
return False
6
return True
7
>>> all_equal(('a','a','a'))
8
True
9
>>> all_equal(['a','c'])
10
False
common_prefix: return a list of common elements at the start of all sequences, then a list of lists that are the unique tails of each sequence.
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
common_prefix
1
>>> def common_prefix(*sequences):
2
if not sequences:
3
return [],[]
4
common = []
5
for elements in itertools.izip(*sequences):
6
if not all_equal(elements):
7
break
8
common.append(elements[0])
9
return common, [sequence[len(common):] for sequence in sequences]
10
>>> s1='/a/b/c/d'
11
>>> s2='/a/b/c1/d1'
12
>>> t1=s1.split('/')
13
>>> t2=s2.split('/')
14
>>> common_prefix(t1, t2)
15
(['', 'a', 'b'], [['c', 'd'], ['c1', 'd1']])
relpath: return a relative path from p1 equivalent to path p2. In particular: the empty string, if p1 == p2; p2, if p1 and p2 have no common prefix.
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
relpath
1
>>> import os
2
>>> def relpath(p1, p2, sep=os.path.sep, pardir=os.path.pardir):
3
common, (u1, u2) = common_prefix(p1.split(sep), p2.split(sep))
4
if not common:
5
return p2
6
return sep.join([pardir]*len(u1) + u2)
7
>>> print 'from', p1, 'to', p2, ' -> ', relpath(p1,p2, '/')
8
from /a/b/c/d to /a/b/c1/d1 -> ../../c1/d1