有没有啥聪明的方法可以在 python 中组合重叠路径?
Posted
技术标签:
【中文标题】有没有啥聪明的方法可以在 python 中组合重叠路径?【英文标题】:Is there any smart way to combine overlapping paths in python?有没有什么聪明的方法可以在 python 中组合重叠路径? 【发布时间】:2015-07-03 11:21:51 【问题描述】:假设我有两个路径名: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"
对于这种情况,是否有任何现成的库函数,或者我必须实现一个?
【问题讨论】:
这是在 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 中组合重叠路径?的主要内容,如果未能解决你的问题,请参考以下文章