我知道我可以使用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
。我的代码怎么说这个奇怪的东西?
答案 0 :(得分:4)
您正在遍历列表和从中删除。因此,当你到达中途点时,列表的第二一半消失,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
循环停止,因为没有更多项可以在左边迭代;迭代索引0
,1
和2
后,列表已缩短到不再有索引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
至少在循环时不会缩短,因此您的迭代不会过早结束。
或者您可以使用单独的索引来选择要添加的字符,每次迭代调整它,然后不从text2
删除:
index = -1
for character in text2:
backwards.append(text2[index])
index -= 1
现在您将迭代len(text2)
次。当然,您不再需要将text
转换为列表,您只需索引到text
。
答案 1 :(得分:2)
您正在删除原始列表中的值
del(text2[-1])
让我们考虑一个示例字符串“star”,索引将是0-3。 在第一次迭代中,您将'r'添加到向后列表,然后从原始列表中删除'r'(最后一个字符),所以现在您有“sta”字符串,但您的迭代次数减少到3.循环保持删除和减少列表大小,减少迭代次数。这导致更早的循环终止。
答案 2 :(得分:0)
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)])