Python 如何加入字符串列表并删除重复的字母(保持链接) 我的名单: 期望输出: 我试过:

Python 如何加入字符串列表并删除重复的字母(保持链接) 我的名单: 期望输出: 我试过:,python,string,list,Python,String,List,使用itertools.groupby,但当一行中有两个重复的字母时(即leasequence->sese停留),它似乎无法正常工作: 正如您所看到的,它仅在最后一个'e'中被删除,这并不理想,因为如果一个字母有两个字符,那么它们将收缩为1。i、 e“突然”变成了“突然” 我正在寻找一种最适合这种情况的方法 先谢谢你 编辑 “我的列表”中没有任何重复项。使用辅助函数,通过删除单词的最长前缀(也是后缀s)来裁剪单词t: def crop(s, t): for k in range(len(

使用
itertools.groupby
,但当一行中有两个重复的字母时(即
leasequence
->
sese
停留),它似乎无法正常工作:

正如您所看到的,它仅在最后一个
'e'
中被删除,这并不理想,因为如果一个字母有两个字符,那么它们将收缩为1。i、 e
“突然”
变成了
“突然”

我正在寻找一种最适合这种情况的方法

先谢谢你

编辑


“我的列表”中没有任何重复项。

使用辅助函数,通过删除单词的最长前缀(也是后缀
s
)来裁剪单词
t

def crop(s, t):
    for k in range(len(t), -1, -1):
        if s.endswith(t[:k]):
            return t[k:]
然后用前面的单词裁剪每个单词:

>>> l = ["volcano", "noway", "lease", "sequence", "erupt"]
>>> ''.join(crop(s, t) for s, t in zip([''] + l, l))
'volcanowayleasequencerupt'

>>> l = ['split', 'it', 'lit']
>>> ''.join(crop(s, t) for s, t in zip([''] + l, l))
'splitlit'

下面是一个强力重复数据消除程序:

def dedup(a, b):
    for i in range(len(b), 0, -1):
        if a[-i:] == b[:i]:
            return a[:-i]
    return a
然后,只需快速浏览:

>>> from itertools import chain, islice
>>> xs = ["volcano", "noway", "lease", "sequence", "erupt"]
>>> xs = [dedup(*x) for x in zip(xs, chain(islice(xs, 1, None), [""]))]
>>> "".join(xs)
'volcanowayleasequencerupt'

当然,这适用于任何长度的列表
xs

在我看来,这是一个更可读的版本:

from functools import reduce


def max_overlap(s1, s2):

    return next(
        i
        for i in reversed(range(len(s2) + 1))
        if s1.endswith(s2[:i])
    )


def overlap(strs):

    return reduce(
        lambda s1, s2:
            s1 + s2[max_overlap(s1, s2):],
        strs, '',
    )


overlap(l)
#> 'volcanowayleasequencerupt'
但是,它还考虑了以前重叠的单词中的“累积”字符:

overlap(['split', 'it', 'lit'])
#> 'split'

如果第三个单词比第二个匹配得更远,你对
l=['split','it','lit']
有什么期望?@HeapOverflow我希望
'splitlit'
是这样的,规则是通过每个单词与前面的单词重叠来裁剪每个单词?@HeapOverflow是的,像这样。这对FWIW有帮助吗,这使用
\uu add\uuu
,这很慢,需要为列表中的每个项目重新分配和复制最多
n
。这就是O(n^2)。稍微快一点的是
\uuuu iadd\uuu
。而且
str.join
比CPython上的任何一个都快,因为预分配保证了
O(n)
性能(以及其他方面)。@MateenUlhaq感谢您的洞察力。事实上,根据OP的要求,我选择的是“最具pythonic”而不是“最高效”的方法:“我正在为此寻找最具pythonic的方法。”
>>> from itertools import chain, islice
>>> xs = ["volcano", "noway", "lease", "sequence", "erupt"]
>>> xs = [dedup(*x) for x in zip(xs, chain(islice(xs, 1, None), [""]))]
>>> "".join(xs)
'volcanowayleasequencerupt'
from functools import reduce


def max_overlap(s1, s2):

    return next(
        i
        for i in reversed(range(len(s2) + 1))
        if s1.endswith(s2[:i])
    )


def overlap(strs):

    return reduce(
        lambda s1, s2:
            s1 + s2[max_overlap(s1, s2):],
        strs, '',
    )


overlap(l)
#> 'volcanowayleasequencerupt'
overlap(['split', 'it', 'lit'])
#> 'split'