首页 > 解决方案 > 如果用 0 分隔,则连接列表中的字符串

问题描述

基本上,每当列表中的两个字符串被一个或多个零分隔时,我都想将它们连接在一起。['a',0,'b']=> ["ab"]

我已经尝试过 yield了,我真的找不到一个好的方法来说明如果你在列表中找到一个零,将下一个非零连接到前一个字符串

我以前使用过产量,但我只是没有正确处理这个问题。请注意,我不坚持使用 yield,它似乎是最有可能的工作方法,因为简单的列表理解不会做到这一点。

样本数据和预期输出:

dataexp = [
    #input                          #expected
    (["a"],                         ["a"]),
    ([0,0,"a","b",],                ["a","b"]),
    ([0,"a","0",],                  ["a","0"]),
    (["a",0,"b",],                  ["ab"]),
    (["a",0,0,"b",],                ["ab"]),
    (["a","b",0],                   ["a","b"]),
    (["a","b","c"],                 ["a","b","c"]),
    (["a",0,"b",0, "c"],            ["abc"]),
    ]

一些示例代码

我只是没有正确处理连接逻辑,只是filter5一次认真的尝试。

dataexp = [
    #input                          #expected
    ([0,0,"a","b",],                ["a","b"]),
    ([0,"a","0",],                  ["a","0"]),
    (["a",0,"b",],                  ["ab"]),
    (["a",0,0,"b",],                ["ab"]),
    (["a","b",0],                   ["a","b"]),
    (["a","b","c"],                 ["a","b","c"]),
    (["a",0,"b",0, "c"],            ["abc"]),
    ]

def filter0(li):
    return [val for val in li if isinstance(val, str)]


def filter3(li):
    pos = -1 
    len_li = len(li)
    while pos < len_li-1:
        pos += 1
        if li[pos] == 0:
            continue
        else:
            res = li[pos]
            yield res

def filter5(li):

    len_li = len(li)
    pos = 2
    p0 = p1 = None

    while pos < len_li-1:
        cur = li[pos]

        if p0 in (0, None):
            p0 = cur
            pos +=1 
            continue

        if cur == 0:
            p1 = cur
            pos += 1
            continue

        elif p1 == 0:
            p0 = p0 + cur
            pos += 1
            continue

        else:
            p1 = cur
            pos += 1
            yield p0

    if p0:
        yield p0
    if p1:
        yield p1


for fn in [filter0, filter3, filter5]:

    name = fn.__name__
    print(f"\n\n{name}:")

    for inp, exp in dataexp:
        try:
            got = list(fn(inp))
        except (Exception,) as e:
            got = str(e)

        msg = "%-20.20s for %-80.80s \nexp :%s:\ngot :%-80.80s:" % (name, inp, exp, got)
        if exp == got:
            print(f"\n✅{msg}")
        else:
            print(f"\n❌{msg}")

我通过将字符串推入一个大List[str]然后"\n".join()它来动态生成html。大多数时候,这很好,浏览器会忽略空格,但赛普拉斯确实关心\nin <td>xyz\n</td>. 所以,与其改变一切,我想我会找到一种方法来使用mylist.extend(0, "</td>"). 但现在我只是好奇这个列表问题的后视/前瞻性质。而且,如果您认为 Django 或 Jinja 模板更适合,那么您是正确的,只是这是生成 Django 模板,而不是最终的 html。

标签: pythonlistiterator

解决方案


我认为在这里使用生成器没有任何好处。您可以跟踪确定您的连接条件的状态并附加或连接:

from typing import List, Literal, List

def process_list(l: List[Union[str, Literal[0]]]) -> List[str]:
    result, concat = [], False
    for e in l:
        if e == 0:
            concat = True
            continue
        if concat and result:
            result[-1] += e
        else:
            result.append(e)
        concat = False
    return result

推荐阅读