在字符串列表中连接选定的字符串

时间:2017-05-02 03:03:51

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

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

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']

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

2 个答案:

答案 0 :(得分:2)

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

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

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

  2. 然后遍历源列表,将元素附加到目标列表,并特别处理'in'的位置,即如果后面的单词在特殊集合中,则加入两个&附加到目标,再一次推进迭代器。

  3. 一旦源列表用完,将抛出一个IndexError,表明我们应该打破循环。

  4. 代码:

    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包围的空格除外。在这里,我们可以使用负向前瞻和回顾后发

    3. 代码:

      import re
      
      c = re.compile(r'(?<!in) (?!weeks)')
      
      lst2 = c.split(' '.join(lst1))
      

答案 1 :(得分:0)

这不是对您的代码的修复,而是一个替代解决方案(我总是最终使用正则表达式)

import math

import matplotlib.pyplot as plt
x = []
y = []
for dimension in range(100):
    n = float(dimension)
    volume = math.pi**(n/2)/math.gamma(n/2 + 1)
    x.append(n)
    y.append(volume)

plt.plot(x, y)
plt.show()

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

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(',') 用于确保我们不会意外地从npis中的内容结尾/开头的单词中删除位数