【问题标题】:concatenate strings in list if separated by 0s如果用 0 分隔,则连接列表中的字符串
【发布时间】:2020-08-09 01:15:17
【问题描述】:

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

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

我以前使用过 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。大多数时候,这很好,浏览器会忽略空格,但赛普拉斯确实关心&lt;td&gt;xyz\n&lt;/td&gt; 中的\n。所以,与其改变一切,我想我会找到一种方法来使用mylist.extend(0, "&lt;/td&gt;") 来抑制换行符。但现在我只是好奇这个列表问题的后视/前瞻性质。而且,如果您认为 Django 或 Jinja 模板更适合,那么您是正确的,只是这是生成 Django 模板,而不是最终的 html。

【问题讨论】:

  • 你为什么不直接删除它们?
  • @AirStalk3r b.c.加入条件不同
  • 哦,我明白了!
  • 删除换行符?我可以,但我宁愿不要到处删除所有换行符,而只是将此调整限制为 html 元素文本。无论如何,在加入之前,在列表级别进行清理似乎很有趣。传入"\n".join() 的任何内容都必须是字符串,因此任何不是字符串的内容显然都是命令元素。

标签: python list iterator


【解决方案1】:

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

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

【讨论】:

  • 不错。我想应该走那条路。我仍然想知道是否可以将 yield 用于需要跟踪多个索引位置的此类问题,或者它是否天生不适合。我暂时将其保持打开状态,看看是否有任何与产量/迭代器相关的好的东西出来,否则你可以拥有它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 2015-09-26
  • 1970-01-01
相关资源
最近更新 更多