当前位置: 首页 > 科技观察

字符串神秘消失之谜

时间:2023-03-19 09:53:13 科技观察

今天在交流群里,有人问了这样一个问题:截图中涉及的图片是:一开始以为是个简单的问题,后来发现不是就这么简单。想来这位同学的代码,在PyCharm中以debug模式运行,效果如下图:截至倒数第二行,con字符串中的数据依然正常。但是一旦使用打印功能打印出来,数据又错了。为了说明这个问题,我写了一段代码来简单复现这个问题。从截图可以看出,a是一个普通的列表,不是生成器。当我们直接通过for循环展开a列表,然后打印里面的数据,就可以正常显示了。但是当我提前使用''.join(a)将a列表中的字符串拼接成一个字符串时,发现只能显示a列表中的最后一个字符串。前两根弦神秘地消失了。为了解释为什么会出现这个问题,我们先看看a列表长什么样子:可以看到,在a列表中,前两个元素的末尾有一个\r。我们来看看使用''.join(a)生成的b字符串长什么样子:注意这里需要直接输入字符串的名字才能显示它的真实面目,不能使用print函数打印它。两者的区别可以看我的文章:【一日一招】揭开字符串的两张“脸”。你能看见它吗?事实上,当我们执行''.join(a)时,它正确地拼接了a列表中的三个字符串,结果是abc\rdef\rxyz\r。但这里不好就是不好\r。这个符号在这里不是制表符,而是告诉输出光标现在移动到行的开头。如何理解这个现象,我们假设现在有9个编号为1-9的水桶和9个编号为1-9的球。正常情况下,球1放入桶1,球2放入桶2,球3放入桶3……球9放入桶9。这就是我们正常的打印流程。但是现在,我们在球3-4之间添加了一个特殊的球,上面写着\r。还要在数字6-7之间添加一个\r球。先把1号球放入1号桶,2号球放入2号桶,3号球放入3号桶。然后,你看到了\r这个球,这个球并没有放入桶中,而是需要回到1号桶,将第4个球放入第1个桶,第5个球放入第2个桶,第6个球放入3号桶,接下来又遇到\r球,回到1号桶,将7号球放入1号桶,将8号球放入2号桶桶,将9号球放入3号桶。经过一些操作,在所有的桶中,最上面的球只有7、8、9号球。其他1-6号球都被覆盖了。注意这里我用的是把球放在桶里的例子,而不是在Word中打字,因为我们在使用Word的时候,如果把光标移到行首输入新的字符,那么现有的字符会被输入到命令。退后。但是我们今天遇到的情况是顺序覆盖的。所以不要混淆这两种情况。为了证明这个顺序覆盖,我们看下面的例子:请记住上面把球放进桶里的例子,\r球没有放进桶里,它告诉你回到开头线。所以,我们的第一个字符串是11111111111,因为后面有一个\r,所以现在回到行首继续输出22222,这里有5个2,所以此时字符串变成了22222111111。这时又遇到了一个\r,于是回到行首,输出333。所以最后的结果是33322111111。这道题的关键是\r,而不是''。join()有什么问题,你甚至可以直接用\r手动输入一个字符串,效果是一样的:另外需要注意的是,这个\r只会影响print函数的打印输出。但是这个字符串本身不会出现\r后面的字符覆盖前面的字符。因此,对于一个字符串aaaaa\rbb,我们可以看到虽然print只打印了bbaaa5个字符,但实际上有8个字符:codeattention。转载本文请联系Code公众号。