【问题标题】: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 开头

标签: python python-3.x string path


【解决方案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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-24
        • 2012-12-27
        • 1970-01-01
        • 2011-02-13
        相关资源
        最近更新 更多