字符串反转只反转一半的字符串

String reversal only reverses half the string

我知道我可以只使用 reverse 函数来反转字符串,但是对于 Codecademy 作业,我试图在没有 reverse[::-1] 的情况下反转字符串。在试图找出我的代码有什么问题时,我偶然发现了问题的可能解决方案,但在这一点上,我只想了解我的代码在做什么。

def reverse(text):
    text2 = list(text)
    backwards = []
    for char in text2:
        backwards.append(text2[-1])
        del(text2[-1])
    return "".join(backwards)

text = raw_input("Say something:\n")

print reverse(text)

当我对此进行测试时,输出始终是字符串的后半部分反转。我不明白为什么 for char in text2: 会被解释为 for half_the_char in text2。我的代码如何解释这种奇怪的情况?

您正在遍历列表 并从中删除。因此,当您到达中间点时,列表的 second 一半消失了,并且 for 循环停止,因为不再有要迭代的项目了。

每次迭代都打印出你的列表,你会看到发生了什么:

>>> text2 = list('hello')
>>> backwards = []
>>> for char in text2:
...     backwards.append(text2[-1])
...     del text2[-1]
...     print 'char:', char, 'backwards:', backwards, 'text2:', text2
... 
char: h, backwards: ['o'] text2: ['h', 'e', 'l', 'l']
char: e, backwards: ['o', 'l'] text2: ['h', 'e', 'l']
char: l, backwards: ['o', 'l', 'l'] text2: ['h', 'e']

for 循环然后停止,因为左边没有更多的项目可以迭代;在遍历索引 012 之后,列表已缩短到不再有索引 3 的程度。

您可以改用 while 循环:

while text2:
    backwards.append(text2[-1])
    del(text2[-1])

现在循环仅在 text2 完全为空时停止。

或者你可以遍历 text,它具有相同的长度和相同的字符;它几乎与您原来的 for 循环一样毫无意义,因为您 忽略 char 循环目标相同:

for char in text:
    backwards.append(text2[-1])
    del(text2[-1])

text 至少在循环时不会缩短,因此您的迭代不会过早结束。

或者您可以使用单独的 index 来选择要添加的字符,每次迭代都对其进行调整,然后 nottext2:

index = -1
for character in text2:
    backwards.append(text2[index])
    index -= 1

现在您将迭代 len(text2) 次。当然,你不需要再将 text 转换为列表,你可以索引到 text.

del(text2[-1]) 行解释了你的怪癖。您正在设置每个字符,但是对于您每一步的字符,您都会从末尾删除一个字符,因此一旦您完成一半,您的字符串将不再剩下任何内容。

与其删除原始字符,不如在前面添加您正在迭代的字符:

for char in text2:
    backwards.insert(0, char)

参考这个问题:What's the idiomatic syntax for prepending to a short python list?

另一种选择是向后遍历字符串并追加到列表中:

for i in range(len(text2)):
    backwards.append(text2[-(i + 1)])

您正在删除原始列表中的值

del(text2[-1])

让我们考虑一个示例字符串 "star",索引为 0-3。 在第一次迭代中,您将 'r' 添加到向后列表,然后从原始列表中删除 'r' (最后一个字符),所以现在您还剩下 "sta" 字符串,但是您的迭代次数减少到3.循环不断删除和减少列表大小,从而减少迭代。这会导致循环提前终止。