【问题标题】:Python, connecting vertical listsPython,连接垂直列表
【发布时间】:2015-01-19 00:14:04
【问题描述】:

我有这个例如这个字符:

.....U......
L...L.######
.S....#.....
....L.......

我存储在一个列表中

chars = ['.....U......', 'L...L.######', '.S....#.....', '....L.......']

我用它来将它存储在字符中:

for x in range(0, N):
    g = input()
    chars.append(g)

现在的问题是我想把字母 L 之间的所有点都变成 # 但垂直,所以像这样:

.....U......
L...L.######
.S..#.#.....
....L.......

我已经尝试了几个小时,但我想不出任何东西。非常感谢您的帮助。

编辑: 我用它来水平连接它们。它有效。

while y != N:
    modchars0 = list(chars[y])

    if modchars0.count('L') == 0:
        y += 1

    else:
        for k in range(0, M):
            if 'L' in modchars0[k]:
                start = k + 1
                break

        for l in range(M-1, 0, -1):
            if 'L' in modchars0[l]:
                end = l
                break

        for h in range(start, end):
            if 'L' in modchars0[h]:
                pass
            else:
                modchars0[h] = '#'

        modchars1 = modchars1.join(modchars0)
        chars[y] = modchars1
        y += 1

【问题讨论】:

  • zip(*chars) 采用chars 的转置。如果您已经有一个横向工作的例程,那么您就已经准备好了。

标签: python string list


【解决方案1】:

正如 cmets 中提到的@U2EF1,您可以使用zip(*chars) 对列表进行转置,然后使用正则表达式您可以将“L”之间的点转换为“#”。然后在最后zip(*) 再次获得新项目以获得所需的输出:

>>> import re                                                             
>>> r = re.compile(r'(?<=L).*(?=L)')                     
>>> def rep(m):                                           
    return m.group().replace('.', '#')
... 
>>> zipped = (r.sub(rep, ''.join(x)) for x in zip(*chars))
>>> for x in zip(*zipped):
    print ''.join(x)
...     
.....U......
L...L.######
.S..#.#.....
....L.......

【讨论】:

  • 压缩和重新压缩是不是有点矫枉过正?这是否击败了具有更长列表或更长字符串列表的更简单的解决方案?不是批评家,我实际上对学习很感兴趣。
  • @Roberto 在计算上超越了矫枉过正,是的。但这似乎主要是教育性的,所以还不错。
  • @Roberto 我不认为 OP 只想用 L#L 替换 L.L,我的解决方案也适用于 L.SLL....L 等情况(OP 说:我想把字母 L 之间的所有点都变成#)。所以,我不认为这是矫枉过正。如果他们只想将L.L 转为L#L,那么这肯定可以以更好的方式完成。
  • @AshwiniChaudhary 是正确的。字符甚至不必是完全相同的宽度和高度,所以你可以得到 L..L..L 等
  • 另外,如果有人想知道这一点,我计划实现 a* 算法以找到从 U 到 S 的最佳路径,#-无法跨越这些
【解决方案2】:

迟到的答复

这可能不值得最佳答案,但仍然是一个替代方案。

首先定义一个将列表从水平旋转到垂直的函数:

def invert(chars):
    inverted = []
    for i in range(len(chars[0])):
        newStr=""
        for j in range(len(chars)):
            newStr+=chars[j][i]
        inverted.append(newStr)
    return inverted

那么你可以这样使用它:

def main():
    chars = ['.....U......', 'L...L.######', '.S....#.....', '....L.......']
    invChars = invert(chars)

    for i in range(len(invChars)):
        invChars[i] = re.sub(r'(?<=L)(\..*?)L', lambda k: k.group().replace('.','#'), invChars[i])

    chars = invert(invChars)

【讨论】:

  • 您的invert 函数可以更简单、更高效地完成(通过避免每次循环重新分配字符串)作为[''.join(c) for c in zip(*chars)]
  • 我不知道输出,但您的代码中有明显的语法错误。所以,最好在发布之前运行它。
  • @AshwiniChaudhary 现在可以工作了...我在 invert 函数中缩进了太多次
  • 请注意,除了this,您的解决方案还将错过重叠组:L.L.L
  • @AshwiniChaudhary 我的原始答案旨在适用于提供的示例,但我仍然进行了编辑。如果我在正则表达式匹配中遗漏了什么,请告诉我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
  • 2014-09-16
  • 2021-06-03
相关资源
最近更新 更多