有没有聪明的方法来组合python中的重叠路径?

时间:2015-04-24 18:07:21

标签: python

我们说我有两个路径名: head tail 。它们可以与任意数量的段重叠。如果他们不想正常加入他们。如果它们重叠,我想检测公共部分并相应地组合它们。更具体一点:如果名称中有重复,我希望找到尽可能长的重叠部分。实施例

"/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"

这种情况下是否有任何现成的库函数,或者我必须实现一个?

4 个答案:

答案 0 :(得分:4)

您可以在join函数中使用列表推导:

>>> 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'

如果差异只是第二个路径的基本名称,您可以使用os.path.basename获取bname并将其连接到p1

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

答案 1 :(得分:3)

我建议您使用difflib.SequenceMatcher后跟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'

解答一般解决方案

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:]

执行

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

答案 2 :(得分:1)

我认为这有效:

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))

请注意,这是一个适用于任何两个字符串的通用解决方案,因此它可能不像仅适用于文件路径的解决方案那样优化。

答案 3 :(得分:0)

我只是在这里寻找答案。希望它可以帮助其他人。
这是我在Nodejs中做到的方式

const path1 = '/root/user/name/code/website/'
const path2 = './website/index.js'

const arrOfDirectories = [...path1.split('/'), ...path2.split('/')] 
// ['', 'root', 'user', 'name', 'code', 'website', '', '.' 'website', 'index.js']

const arrOfUniqueDirectories = arrOfDirectories.filter((value, index, self) => self.indexOf(value) === index)
// ['', 'root', 'user', 'name', 'code', 'website', '', '.','index.js']

const jankyPath = arrOfUniqueDirectories.join('/')
// /root/user/name/code/website./index.js

const myPath = path.normalize(jankyPath)
// myPath = /root/user/name/code/website/index.js