【问题标题】:Concatenating selected strings in list of strings连接字符串列表中的选定字符串
【发布时间】:2017-09-29 11:26:03
【问题描述】:

问题如下。我有一个字符串列表

lst1=['puffing','his','first','cigarette','in', 'weeks', 'in', 'weeks']

我想获取字符串

lst2=['puffing','his','first','cigarette','in weeks', 'in weeks']

即连接子列表['in', 'weeks'] 的任何出现,原因与此处无关,其中find_sub_list1 取自here(并包含在下面的代码中):

npis = [['in', 'weeks'], ['in', 'ages']]

# given a list a candidate sublist, return the index of the first and last
# element of the sublist within the list
def find_sub_list1(sl,l):
    results=[]
    sll=len(sl)
    for ind in (i for i,e in enumerate(l) if e==sl[0]):
        if l[ind:ind+sll]==sl:
        results.append((ind,ind+sll-1))

    return results

def concatenator(sent, npis):
    indices = []
    for npi in npis:
        indices_temp = find_sub_list1(npi, sent)
        if indices_temp != []:
            indices.extend(indices_temp)
    sorted(indices, key=lambda x: x[0])

    for (a,b) in indices:
        diff = b - a
        sent[a:b+1] = [" ".join(sent[a:b+1])]
        del indices[0]
        indices = [(a - diff, b - diff) for (a,b) in indices]

    return sent 

此编码器返回的不是所需的lst2

concatenator(lst1,['in', 'weeks'])
>>['puffing','his','first','cigarette','in weeks', 'in', 'weeks']

所以它只连接第一次出现。关于代码在哪里失败的任何想法?

【问题讨论】:

  • 连接这两个词的更好方法是向后工作。这样您就不必使用 diff 调整剩余的索引
  • 我怎么错过了!好建议!非常感谢!

标签: python string list python-3.x tuples


【解决方案1】:

因为所需的子序列是'in' 'weeks' 可能还有'in''ages'

一种可能的解决方案可能是(虽然循环不是很优雅):

  1. 先找出所有出现'in'的位置。

  2. 然后遍历源列表,将元素追加到目标列表,并对'in'的位置进行特殊处理,即如果后面的单词在特殊集合中,则将两者连接并追加到目标,将迭代器向前推进一次。

  3. 一旦源列表用完,就会抛出一个IndexError,指示我们应该中断循环。

代码:

index_in = [i for i, _ in enumerate(lst1) if _ == 'in']

lst2 = []; n = 0

while True:
    try:
         if n in index_in and lst1[n+1] in ['weeks', 'ages']:
             lst2.append(lst1[n] + lst1[n+1])
             n += 1
         else:
             lst2.append(lst1[n])
         n += 1
     except IndexError:
         break

更好的方法是通过正则表达式。

  1. 将列表加入以空格为分隔符的字符串

  2. 在空格上拆分列表,in<space>weeks 包围的空格除外。在这里,我们可以使用否定的lookahead & lookbehind

代码:

import re

c = re.compile(r'(?<!in) (?!weeks)')

lst2 = c.split(' '.join(lst1))

【讨论】:

    【解决方案2】:

    这不是对您的代码的修复,而是另一种解决方案(我最终总是对所有内容都使用正则表达式)

    import re
    list1_str = ','.join(lst1)
    npis_concat = [','.join(x) for x in npis]
    for item in npis_concat:
        list1_str = re.sub(r'\b'+item+r'\b',item.replace(',', ' '),list1_str)
    lst1 = list1_str.split(',')
    

    我在这里使用逗号,但您可以将其替换为任何字符,最好是您知道不会出现在文本中的字符

    r'\b' 用于确保我们不会意外地从以 npis 中的内容结尾/开头的单词中截取位

    【讨论】:

      猜你喜欢
      • 2017-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      • 2018-11-14
      • 1970-01-01
      相关资源
      最近更新 更多