如何加入字符串列表并删除重复的字母(保持链接)

2024-09-30 14:16:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我的名单:

l = ["volcano", "noway", "lease", "sequence", "erupt"]

期望输出:

'volcanowayleasequencerupt'

我试过:

使用itertools.groupby但当行中有两个重复的字母(即leasesequence->;sese)时,它似乎不起作用:

>>> from itertools import groupby
>>> "".join([i[0] for i in groupby("".join(l))])
'volcanonowayleasesequencerupt'

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

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

先谢谢你

编辑

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


Tags: fromgt字母sequencejoinitertoolsgroupby名单
3条回答

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

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

使用辅助函数,通过删除单词的最长前缀(也是后缀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'

在我看来,更具可读性的版本是:

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'

相关问题 更多 >

    热门问题