记工作中遇到的两个Python字符串问题

           今天工作中写了一个Python脚本,目的是想处理一个数据集合。这个数据集合中放的是百度搜索卡片中某个类目下的搜索信息。首先读入一个列表,这个列表存放了每个搜索串的名称name,访问量pv,百度百科位置(即在搜索结果中显示在第几条)pos,唯一标识id以及百科url信息,存放格式如下:

        name (\t) pv (\t) pos1:id1:url1 (space) pos2:id2:url2

        (其中 pos:id:url串可能有一个或多个)

        按行读入这个文件后,将这些数据按照如下格式保存为一个字典:

        {name, [pv, [[pos1, id1, url1], [pos2, id2, url2]]]}


        使用如下脚本处理:


                         记工作中遇到的两个Python字符串问题


       运行后发现结果不对,如原始数据格式截图如下(取前10条搜索数据)

记工作中遇到的两个Python字符串问题


          发现这些数据中有一些乱码。使用上述脚本处理后打印出 query_dict字典看看几条数据:

      记工作中遇到的两个Python字符串问题


           看到对第一条数据来说,name是 ' 双眼皮修复',但打印字典的时候变成了 '\x01\xe5'等等值。第一个疑问就是字符串的编码格式怎么变化了。通过试验,发现是python2.x下编码格式的问题(在python3.6下没有发现这个问题)。我的脚本中指定编码格式为utf-8,而python2内部编码为unicode。当打印字符串时可以正常打印出汉字,而打印数据结构,如dict或dict.keys()时,就会打印出Unicode。因此虽然看上去不一致,但仅仅是编码问题。

        第二个问题是在处理结果中应该出现 [pos, id, url]的位置却是空list,这很奇怪。在代码中加上打印日志,发现问题出在第36行。在这里我把原始数据中读入的每一个 pos:id:url组使用split(':')分解成list,然后检查url中是否有baike.baidu.com这个字符串,由于url都是以 http:// 开头,因此实际上还有一个隐藏的冒号。下一行的item_list[2] 实际是 'http'!这导致所有数据全部丢弃了。

        以前没有关注过split 这个方法,上网一查发现只需要使用 split(':', 2),即可只分割前两个冒号,而后面的所有内容全部放在一起,不再分割。因此把 split(':') 改成 split(':', 2) 就OK了。


        总结:通过写一个简单的Python脚本,学习了两个以前没有注意到的Python特性。首先是编码格式,通常在代码前面需要指定编码格式,一般指定为utf-8。而在Python2.x中,直接打印数据结构和打印字符串时使用的编码格式是不同的。第二个就是在使用split()函数时,要尤其注意分割符有没有可能出现在每个部分的内部,如果是这样结果就不会符合预期。可以在split()中加一个参数来控制数量。从中也可以看出Python中很多看起来很简单的函数,也有很多用法需要我们去学习。