2

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

示例输入:

['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])

请帮忙。

谢谢

4

2 回答 2

5

您可以使用“解压缩”(即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可以将生成器表达式作为参数,在这种情况下生成器表达式是

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

表达方式

zip(*a)

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

中的索引

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

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


编辑

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

于 2020-04-27T08:19:36.837 回答
4

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

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
于 2020-04-27T07:17:49.483 回答