2.6 思考与提高

下面我们列出几道常见的涉及本章知识点的Python面试题并附上答案。苏格拉底说,未经审视的人生,不值得一过。类似地,未经独立思考的问题,不值得一做。请读者尝试给出自己的答案,之后再查看参考答案,这样更有价值。

1.请针对如下两个列表编写一段Python代码,实现功能:如果元素不相同则两两封装成一个元组,并将所有这样的元组打包成一个列表。预期的结果是,[(1, 2), (1, 7), (2, 7), (3, 2), (3, 7)]。

【案例分析】

这里考察的是列表推导式中的for循环嵌套。

【参考代码】

2.在Python里面如何实现元组和列表的转换?

【案例分析】

元素和列表都是一种数据类型,在面向对象编程里,都有构造函数的概念。构造函数里的参数可以接纳元组或列表。所以,分别用tuple(元组名)或list(列表名)来实现即可。

【参考代码】

3.请编写一段Python代码,删除一个列表里面的重复元素。

【案例分析】

此题有两种解决方案,分别是集合去重法和字典去重法。

【参考代码】

考察Python几个基本数据类型的特性,其中集合的特性就是元素不能重复。所以第一种解决方案就是利用集合的特性。代码如下。

在In [18]处,我们先把a_list列表集合化,即去重,然后将集合列表化,即把无序的集合重新变成有序的列表,最后把经过“净化”处理的列表重新赋值给a_list。

细心的读者可以用内置函数id()来监控“净化”前后两个a_list的内存地址有无变化,然后你会发现,二者的地址并不相同。也就是说,事实上编译器完成了一个漂亮的“狸猫换太子”的过程。

我们知道,作为以键/值对为元素特征的字典,它的值是任意的,但键必须独一无二。其实这个特性也可以拿来做列表的去重。参考图2-16中所示的代码。

图2-16 利用字典中的键对列表去重

在图2-16所示的代码中,在In [22]处的for循环中,我们把列表a_list中的元素逐一取出来,作为字典a_dict的键,这样可以达到的效果就是“同键归一”,而字典a_dict的值等于什么,我们是无所谓的,不过是“格式所迫”,随便赋一个罢了。

在In [23]处,我们利用字典的keys()方法提取字典中所有元素的键,然后再利用list()将其转换为列表。

对比这两种方案,显然,方案1更加简单。但我们的目的在于,通过不断的“折腾”,让自己对Python数据结构的基本特性逐渐熟悉起来。

4.在机器学习领域,我们经常要做数据的预处理,例如,把不合格的数据删除,或把实际相同但描述不同的对象(比如名字大小写不同)合并。假定我们有如下列表:

现在我们要求将姓名长度小于2字符的删除(通常姓名的字符长度大于3),将写法相同但大小写不一样的名字合并,并按照习惯变成首字母大写,对于上面的列表,我们希望得到的结果如下。

【案例分析】

本题考察的是集合推导式。

【参考代码】

在In [26]处,我们利用了字符串的大写函数upper()和小写函数lower()上述问题也可以这样解决:{name.title() for name in names if len(name)>2}。title()正是将名字的首写字母变为大写的函数。

5.请设计Python程序,完成要求的功能。假设我们有如下字典,键为字母,现在我们希望“键”不区分大小写,而将“值”合并。例如,以下字典

经过处理后,希望达到的效果如下。

【案例分析】

这里考察的知识点是字典推导式。

【参考代码】

在上面的代码中,我们使用了字典中的方法get(key, default=None),其功能是返回指定键的值,如果值不在字典中,则返回default指定的默认值。在本例中这个默认值为0。

通过前面题目的训练,我们能不能实现对第4题列表中所有重名人员进行计数,并以字典的形式表示出来呢?要求其输出格式如下。

这个问题的答案,就留给爱思考的你来给出吧!

在前面的题目中,部分知识点或部分函数的使用,我们并没有提及,看起来知识覆盖并不全面。事实上,Python博大精深,不是任何一本书能囊括的。这里,我们推崇一种学习理念,就是“做中学(learning by doing)”,不要指望学好所有知识再上手Python工程,而是应该在掌握基础知识后直接上手,在这期间会发现很多你不知道、不明白的知识点。这时,三位老师的价值,就显得非常重要了。这三位老师分别是谷老师(谷歌)、必老师(必应)和百老师(百度),有事多请教,你会发现,他们几乎什么都知道!