有没有啥聪明的方法可以在 python 中组合重叠路径?

Posted

技术标签:

【中文标题】有没有啥聪明的方法可以在 python 中组合重叠路径?【英文标题】:Is there any smart way to combine overlapping paths in python?有没有什么聪明的方法可以在 python 中组合重叠路径? 【发布时间】:2015-07-03 11:21:51 【问题描述】:

假设我有两个路径名:headtail。它们可以与任意数量的段重叠。如果他们不这样做,我想正常加入他们。如果它们重叠,我想检测共同部分并相应地组合它们。更具体地说:如果名称中有重复,我想找到尽可能长的重叠部分。示例

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

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

【问题讨论】:

这是在 Django 中吗?还是只是 python? 这些路径会在运行代码的同一台机器上吗? 总是从 /root 开始吗?如果两者都是d1/d2,结果应该是什么? 没有 django,只有 python;不一定是同一台机器;不一定以 /root 开头 【参考方案1】:

您可以在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'

【讨论】:

有效!你是天才! 这个答案很好,但如果 p1="/root/d1/d2/d1/d2" p2="d2/d1/d2/d2/file.txt" 而不是最后的字符串将是“/root/d1/d2/d1/d2/file.txt”而不是“/root/d1/d2/d1/d2/d2/file.txt”我的意思是任何文件夹p2与 p1 的共享必须始终具有唯一名称,如果不是,则其他同名文件夹将从 p1.split("/") 中的 not 中删除。 它不适用于:p1 = "/root/b/a" p2 = "a/b/file.txt" p1 + '/' + '/'.join([i for i在 p2.split('/') 如果我不在 p1.split('/')])【参考方案2】:

我建议您使用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'

【讨论】:

【参考方案3】:

我认为这可行:

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

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

【讨论】:

【参考方案4】:

我只是在这里寻找这个答案。希望它可以帮助别人。 这是我在 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

【讨论】:

以上是关于有没有啥聪明的方法可以在 python 中组合重叠路径?的主要内容,如果未能解决你的问题,请参考以下文章

电脑桌面操作不了,咋办

组合多个对象并在python中创建重叠属性列表

有啥方法可以在python2中录制音频? (苹果电脑)

《聪明的投资者》

java中的组合和聚合有啥区别? [复制]

合并两个重叠列表的Pythonic方法,保留顺序