【问题标题】:Algorithm to concatenate a list of strings in zig-zag fashion以之字形方式连接字符串列表的算法
【发布时间】:2020-04-27 07:10:51
【问题描述】:

我有以下问题:从字符串列表中,我必须从所有字符串中取第一个字母,之后(从后到前),我必须取第二个字母,在第三个字母之后从前面到结束等等。

示例输入:

['abcd', 'efgh', 'ijkl', 'mnop']

输出应该是:

'aeimnjfbcgkoplhd'

到目前为止,第一个“for”附加到数组中:aeim 和 cgko 第二个“for”附加到数组:njfb 和 plhd。反正顺序不好,我需要aeim + njfb + cgko + plhd

array = []
if len(list_of_strings[0]) % 2 == 0: # if we have strings with even number of letters
    for j in range(len(list_of_strings[0]/2)): # range(2) in our example
        for i in range(len(list_of_strings)): # range(4) in our example
            array.append(list_of_strings[i][j*2])

    for j in range(1, len(list_of_strings[0]), 2): # range(1, 4, 2) in our example
        for i in range(len(list_of_strings) - 1, -1, -1): # range(3, -1, -1) in our example
            array.append(list_of_strings[i][j])

请帮忙。

谢谢

【问题讨论】:

    标签: python python-3.x list zigzag


    【解决方案1】:

    您可以使用"unzip" (i.e. zip(*a))str.join 使用简单的单行:

    a = ['abcd', 'efgh', 'ijkl', 'mnop']
    b = ''.join(''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a)))
    assert b == 'aeimnjfbcgkoplhd'
    

    join 可以将generator expression 作为参数,在这种情况下生成器表达式是

    ''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a))
    

    表达式

    zip(*a)
    

    解压缩a 中的字符串,即它返回一个生成器,该生成器生成包含每个字符串的所有第一个字母、所有第二个字母等的元组。

    索引

    t[::1-2*(i%2)]
    

    确保我们在每第二次迭代时反转元组的顺序。


    编辑

    我对我的单线与@cs95's answer 进行了基准测试,两者的性能在误差范围内是相同的。我认为在“真实代码”中,我更喜欢他的解决方案,因为它更清晰。

    【讨论】:

      【解决方案2】:

      将字符视为二维数组中的元素:

      a b c d
      e f g h
      i j k l
      m n o p
      

      我们想在奇数列上向下,然后在偶数列上向上,所以我们这样做:

      chars = []
      for i in range(len(l[0])):
          for w in l[::1 if i  % 2 == 0 else -1]:  
              chars.append(w[i])
      print(''.join(chars))
      # aeimnjfbcgkoplhd
      

      l[::1 if i % 2 == 0 else -1] 将反转偶数列的列表,因此我们从末尾挑选字符。这是直观但丑陋的,因为对列表进行切片会创建一个浅拷贝。我们可以做一些更聪明的事情,通过使用 mod 来确定是否反向迭代:

      chars = []
      for i in range(len(l[0])):
          for j in range(len(l)) if i % 2 == 0 else reversed(range(len(l))):
              chars.append(l[j][i])
      print(''.join(chars))
      # aeimnjfbcgkoplhd
      

      【讨论】:

      • 非常感谢您的解决方案以及我应该如何思考的提示!
      • @alex_mucenic 辛苦了,好问题,谢谢。
      • @alex_mucenic PS 我添加了第二个解决方案,展示了如何为内部循环切换迭代方向pythonically,PTAL
      • @cs95 至少对于给定的(短)输入,“更聪明”的解决方案实际上比第一个解决方案慢很多(在我的机器上是 2.68µs 而不是 1.93µs)。只创建一次reversed(range(len(l))) 可能更快。
      • @cs95 range(len(l)-1, -1, -1) 也比反转范围更快。
      猜你喜欢
      • 1970-01-01
      • 2018-11-14
      • 2017-04-24
      • 2018-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-06
      • 2023-03-03
      相关资源
      最近更新 更多