繁体   English   中英

如果符合条件,则在列表中连接连续的字符串对

[英]Join consecutive pairs of strings in a list if they meet a condition

给出两个列表:

list1 = ["a","b","c","d","e","f","b","c","b","d","f","c","b","e"]
list2 = ["b","c"]

假设len(list2) == 2

我想知道如何获得这样的输出:

['a', 'bc', 'd', 'e', 'f', 'bc', 'b', 'd', 'f', 'c', 'b', 'e']

基本上list1中的list2的任何实例(按此顺序)应该在原始list1和输出中连接(在检查所有可能性之后)。

到目前为止我尝试了什么:

l = len(list1)

for i in range(0,l-1):
    if list1[i] == list2[0]:
        if list1[i+1] == list2[1]:
            a = i
            b = i+1
            list1[a:b+1] = [''.join(list1[a:b+1])]
            l = l - 1
            print(list1)

但不断收到错误:

if list1[i] == list2[0]: IndexError: list index out of range

试试这个,应该适用于任何长度的list2

split_pattern = ''.join(list2)
chunks = ''.join(list1).split(split_pattern)

result = list(chunks[0])
for c in chunks[1:] :
    result.append( split_pattern )
    result.extend( list(c) )

检查result

>>> result
['a', 'bc', 'd', 'e', 'f', 'bc', 'b', 'd', 'f', 'c', 'b', 'e']

假设问题是你收到错误的原因,这一行

                list1[a:b+1] = [''.join(list1[a:b+1])]

修改list1,实际上缩短了它。 因此,当您在列表1的长度范围内循环时,使列表缩短意味着循环计数器i最终将超出范围,因为您希望使用索引查找的列表元素不见了。

您还需要记住列表的索引从0n - 1 ,其中n是列表的长度,所以这个语句

if list1[i+1] == list2[1]:

看起来确实应该如此

if list[i] == list2[0]:

此外部循环基于range(0, l - 1)意味着它将遍历除最后一个索引之外的每个索引。 因此,除非你真的想避免查看列表的最后一个元素,我根据你的要求不认为你做了,你会使用range(l) ,它产生从0 to l - 1索引。

这是使用列表切片的一种方法。

例如:

list1 = ["a","b","c","d","e","f","b","c","b","d","f","c","b","e"]
list2 = ["b","c"]

l = len(list2)
result = []
skip = 0
for i, v in enumerate(list1):
    if skip:
        skip -= 1
        continue
    if list1[i:l+i] == list2:           #Check for sub-element
        result.append("".join(list2))
        skip = l-1                      #Skip flag
    else:
        result.append(v)
print(result)

输出:

['a', 'bc', 'd', 'e', 'f', 'bc', 'b', 'd', 'f', 'c', 'b', 'e']

试试这个:

list1 = ["a","b","c","d","e","f","b","c","b","d","f","c","b","e"]
list2 = ["b","c"]
l = len(list1)
new_list = []
last_merge = False

for i in range(0,l):
    # match list1 index i element with list2 first element
    if list1[i] == list2[0]:
        # match list1 index i+1 element with list2 second element
        if i+1 <= l and list1[i+1] == list2[1]:
            # merge and append list1 index i and i+1 element
            new_list.append(list1[i]+list1[i+1])
            # mark merge as true
            last_merge = True
        else:
            # append list1 index i element
            new_list.append(list1[i])
    else:
        # check list index i element is merge with last element then mark last_merge as False and continue iterate list
        if last_merge is True:
            last_merge = False
            continue

        # append list1 index i element
        new_list.append(list1[i])

print(new_list)

O / P:

['a', 'bc', 'd', 'e', 'f', 'bc', 'b', 'd', 'f', 'c', 'b', 'e']

具有任意list2长度的版本:

def sublist_concatenate(list1, list2):
    N = len(list2)
    fullset = ''.join(list2)
    outlist = []
    i = 0  # counts the number of matches so far

    for el in list1:
        if el == list2[i]:  # hold matching elements so far
            i += 1
            if i == N:  # we have matched N times, so we have the whole set
                outlist.append(fullset)
                i = 0
        else:  # not a match for the next position
            outlist += list2[0:i] # add all previously-passed elements
            # check whether it is a match for the first position though
            if el == list2[0]:
                i = 1
            else:
                outlist.append(el)
                i = 0

    return outlist


l1 = ["a", "b", "b", "c", "d", "e", "f",
      "b", "c", "b", "d", "f", "c", "b", "e"]
l2 = ["b", "c"]

print sublist_concatenate(l1, l2)
# ['a', 'b', 'bc', 'd', 'e', 'f', 'bc', 'b', 'd', 'f', 'c', 'b', 'e']

编辑:每个评论修复的代码,添加if el == list2[0]分支。

def new_f(l1,l2):
    for i,j in zip(l2,l1):
        if i!=j:
            return False
    return True


def func(l1,l2):

    res=[]    
    index = 0    
    l2_string = ''.join(l2)

    while index<len(l1):        
        if l1[index]==l2[0] and new_f(l1[index:index+len(l2)], l2):          # if first element found then checck compare with list2
            # compare with list2 if elemnt match with first elment of list2
            res.append(l2_string)
            index+=len(l2)
        else:
            res.append(l1[index])               
        index+=1
    return res

list1 = ["a", "b","b", "c", "d", "e", "f", "b", "c", "b", "d", "f", "c", "b", "e"]
list2 = ["b", "c"]

result= func(list1,list2)
print(result)

产量

    ['a', 'b', 'bc', 'e', 'f', 'bc', 'd', 'f', 'c', 'b', 'e']

我想建议这个返回生成器的方法:

def join_if_ref(main_list, ref_list):
  n, s = len(ref_list), "".join(ref_list)
  i, size = 0, len(main_list)
  while i < size-n+1:
    j = "".join(main_list[i:i+n])
    if j == s:
      yield j
      i += n - 1
    else:
      yield main_list[i]
    if i < size: i += 1
  for k in range(size-i):
    yield(main_list[k+i])

在这种情况下:

list1 = ["a","b","c","d","e","f","b","c","b","d","f","c","b","c","d","k","s"]
list2 = ["b","c","d"]

它返回:

res = join_if_ref(list1, list2)
print(list(res))
#=> ['a', 'bcd', 'e', 'f', 'b', 'c', 'b', 'd', 'f', 'c', 'bcd', 'k', 's']

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM