我有个关于某个代码的问题。我在python中做了一个关于字符串的练习。我想出了正确的逻辑,但由于某种原因,for循环中的输出没有正确返回。相反,返回全局值。我不太熟悉Python,但是有什么方法可以解决这个问题吗?
def song_decoder(song):
global Ret
Ret = ""
Ret = song.replace("WUB", " ")
Ret = Ret.strip()
Ret += "1"
space = False
for i in range(0, len(Ret)):
if Ret[i] == "1":
Ret = Ret[:i]
break
elif Ret[i] == " ":
if space is False:
space = True
else:
if i+1 == len(Ret):
Ret = Ret[:i]
else:
Ret = Ret[:i] + Ret[(i+1):]
else:
space = False
return Ret测试代码:
def test_song_decoder(self):
self.assertEquals(song_decoder("AWUBBWUBC"), "A B C","WUB should be replaced by 1 space")
self.assertEquals(song_decoder("AWUBWUBWUBBWUBWUBWUBC"), "A B C","multiples WUB should be replaced by only 1 space")
self.assertEquals(song_decoder("WUBAWUBBWUBCWUB"), "A B C","heading or trailing spaces should be removed")第二个测试失败,然后返回'A B C'。
发布于 2015-05-28 21:26:56
首先,您没有必要在这里使Ret成为全局的。所以最好去掉那条线。
第二,缺少一个测试,它将给您另一个提示:
>>> song_decoder("AWUBBWUBC")
'A B C'
>>> song_decoder("AWUBWUBBWUBWUBC")
'A B C'
>>> song_decoder("AWUBWUBWUBBWUBWUBWUBC")
'A B C'如您所见,两个WUB被正确地替换为一个空格。当有三个时,问题就出现了。这应该会给您一个提示,即在进行替换之后,空间检测不能正常工作。这样做的原因其实相当简单:
# you iterate over the *initial* length of Ret
for i in range(0, len(Ret)):
# ...
elif Ret[i] == " ":
if space is False:
space = True
else:
# when you hit a space and you have seen a space directly
# before then you check the next index…
if i+1 == len(Ret):
Ret = Ret[:i]
else:
# … and remove the next index from the string
Ret = Ret[:i] + Ret[(i+1):]
# now at the end of the loop, `i` is incremented to `i + 1`
# although you have already removed the character at index `i`
# making the next character you would have to check belong to
# index `i` too因此,结果是跳过第二个空格后直接出现的字符(移除该字符)。所以不可能这样检测到三个空格,因为你总是跳过第三个空格。
一般来说,在进行修改时迭代一些内容是一个非常糟糕的主意。在您的例子中,您正在迭代字符串的长度,但是字符串实际上一直在变短。所以你真的应该避免那样做。
与其迭代Ret字符串,不如迭代原始字符串,保持不变:
def song_decoder(song):
# replace the WUBs and strip spaces
song = song.replace("WUB", " ").strip()
ret = ''
space = False
# instead of iterating over the length, just iterate over
# the characters of the string
for c in song:
# since we iterate over the string, we don’t need to check
# where it ends
# check for spaces
if c == " ":
# space is a boolean, so don’t compare it against booleans
if not space:
space = True
else:
# if we saw a space before and this character is a space
# we can just skip it
continue
else:
space = False
# if we got here, we didn’t skip a later space, so we should
# include the current character
ret += c
return ret发布于 2015-05-28 21:27:23
你在试图将多个空格折叠成一个空间时遇到了太多的麻烦:
def song_decoder(song, delimiter="WUB"):
splits = song.split(delimiter) # instead of replacing, just split on your delimiter
cleaned = filter(None, splits) # remove empty elements caused by consecutive WUBs
return ' '.join(cleaned) # join them up with a single space in betweenhttps://stackoverflow.com/questions/30517174
复制相似问题