【问题标题】:Concatenate lists and remove overlaps连接列表并删除重叠
【发布时间】:2017-04-12 09:32:42
【问题描述】:

对于我想要的两个列表

A = [ 1,2,3,4,5]
B = [4,5,6,7]

结果 C = [1,2,3,4,5,6,7]

如果我指定重叠 2。

到目前为止的代码:

concat_list = []
word_overlap = 2

for lst in [lst1, lst2, lst3]:
  if (len(concat_list) != 0):

    if  (concat_list[-word_overlap:] != lst[:word_overlap]):
        concat_list += lst
    elif ([concat_list[-word_overlap:]] == lst[:word_overlap]): 

        raise SystemExit

  else:
    concat_list += lst

为字符串列表做这件事,但应该是一样的。

编辑:

我希望我的代码做的是,首先检查是否有任何重叠(1 个、2 个等),然后连接列表,消除重叠(所以我不会得到双元素)。

[1,2,3,4,5] + [4,5,6,7] = [1,2,3,4,5,6,7]

但是

[1,2,3] + [4,5,6] = [1,2,3,4,5,6]

我希望它也检查任何小于我设置的 word_overlap 的重叠。

【问题讨论】:

  • lst1 = [ 1,2,3,4,5] lst2 = [4,5,6,7] c = lst1 + lst2 print list(set(c)) 连接列表的简单方法

标签: python list concatenation


【解决方案1】:

这是一个幼稚的变体:

def concat_nooverlap(a,b):
    maxoverlap=min(len(a),len(b))
    for overlap in range(maxoverlap,-1,-1):
        # Check for longest possible overlap first
        if a[-overlap:]==b[:overlap]:
            break  # Found an overlap, don't check any shorter
    return a+b[overlap:]

使用支持按引用切片的类型(例如缓冲区或 numpy 数组)会更有效。

这样做的一件很奇怪的事情是,在达到重叠=0 时,它会将 a 的整体(切片,它是列表的副本)与 b 的空切片进行比较。除非它们为空,否则该比较将失败,但它仍然保留重叠 = 0,因此返回值是正确的。我们可以通过稍微重写来专门处理这种情况:

def concat_nooverlap(a,b):
    maxoverlap=min(len(a),len(b))
    for overlap in range(maxoverlap,0,-1):
        # Check for longest possible overlap first
        if a[-overlap:]==b[:overlap]:
            return a+b[overlap:]
    else:
        return a+b

【讨论】:

    【解决方案2】:

    你可以使用set和联合

    s.union(t): 包含来自 s 和 t 的元素的新集合

    >> list(set(A) | set(B))
    [1, 2, 3, 4, 5, 6, 7]
    

    但是您无法通过这种方式获得需要重叠的确切数字。

    要回答你的问题,你必须巧妙地使用组合:

    • 获取包含 A 和 B 元素的新列表
    • 获取包含 A 和 B 共有元素的新列表
    • 使用切片仅获取此列表中所需的元素数量

    • 获取新列表,其中包含 A 或 B 中的元素,但不能同时包含

      OVERLAP = 1
      
      A = [1, 2, 3, 4, 5]
      B = [4, 5, 6, 7]
      
      C = list(set(A) | set(B)) # [1, 2, 3, 4, 5, 6, 7]
      D = list(set(A) & set(B)) # [4, 5]
      D = D[OVERLAP:] # [5]
      
      
      print list(set(C) ^ set(D)) # [1, 2, 3, 4, 6, 7]
      

    只是为了好玩,单线可以给这个:

    list((set(A) | set(B)) ^ set(list(set(A) & set(B))[OVERLAP:])) # [1, 2, 3, 4, 6, 7]
    

    OVERLAP 是你需要重聚的常数。

    【讨论】:

    • 我刚刚意识到我可能跑题了,如果我的回答对你有任何帮助,你能准确地说吗?谢谢@Qubix
    【解决方案3】:

    不确定我是否正确解释了您的问题,但您可以这样做:

    A = [ 1,2,3,4,5]
    B = [4,5,6,7]
    
    overlap = 2
    
    print A[0:-overlap] + B
    

    如果您想确保它们具有相同的值,您的检查可以是:

    if(A[-overlap:] == B[:overlap]):
       print A[0:-overlap] + B
    else:
       print "error"
    

    【讨论】:

      【解决方案4】:

      假设两个列表都是连续的,并且列表 a 的值总是小于列表 b。我想出了这个解决方案。 这也将帮助您检测重叠。

      def concatenate_list(a,b):
          max_a = a[len(a)-1]
          min_b = b[0]
          if max_a >= min_b:
              print 'overlap exists'
              b = b[(max_a - min_b) + 1:]
          else:
              print 'no overlap'
          return a + b
      

      对于字符串,你也可以这样做

      def concatenate_list_strings(a,b):
          count = 0
          for i in xrange(min(len(a),len(b))):
              max_a = a[len(a) - 1 - count:]
              min_b = b[0:count+1]
      
              if max_a == min_b:
                  b = b[count +1:]
                  return 'overlap count ' + str(count), a+b
              count += 1
          return a + b
      

      【讨论】:

      • 您想使用上述相同的概念和假设来连接字符串吗?
      • 字符串列表,是的
      • 字符串是指数字字符串 (['1','2'.'3']) 还是单词字符串 ['abc','def']?
      • ["some", "string", "goes", "in", "this", "list" ] 类似这样的列表。
      猜你喜欢
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-15
      • 1970-01-01
      • 2017-09-17
      • 2023-04-06
      • 2019-05-10
      相关资源
      最近更新 更多