Python一行流:像专家一样写代码
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

使用列表解析找出最高收入者

在本节中,你将会学习使用一种漂亮、强大和高效的Python特性——列表解析来创建列表。在接下来的很多一行流程序里你都会用到它。

基础背景

假设你在一家大公司的人力资源部门工作,需要找到所有年薪至少10万美元的员工。你希望输出一个元组的列表,每个元组由两个值组成:员工姓名和员工的年薪。下面是你开发的代码:

尽管这段代码是正确的,但有一种更容易写也更简洁,因而也更易读的写法,可以达到相同的效果。在所有其他条件相同的情况下,行数更少的解决方案能让阅读者更快地捕捉到代码的含义。

Python提供了一种强大的方法来生成新列表:列表解析。语法很简单,如下所示:

方括号表示结果是一个新列表,上下文决定了要选择哪些列表元素,表达式定义了在把元素添加到列表之前,要对它们进行怎样的修改。下面是一个例子:

上面的公式中的for x in range(3)是上下文,剩下的部分x*2是表达式。简而言之,上下文负责生成0,1,2序列,表达式把它们都乘以了2。于是,这个列表解析语句生成了下面的列表:

表达式和上下文要写得多复杂都可以。表达式可以是上下文中定义的任何变量的函数,可以进行任意计算,甚至可以调用外面的函数。表达式的目的就是在将每个列表元素添加进新的列表之前,先对其进行修改。上下文由一个或多个for循环中定义的一个或多个变量构成,你还可以通过if语句来限制上下文的范围。在这种情况下,只有当一个新值符合用户指定的条件时,才会把它加到列表中。

列表解析最好用例子来解释。仔细研究下面的例子,你会对列表解析有一个良好的感觉。

表达式➊:是一个恒等表达式(不会对上下文中传过来的x做任何改动)。

上下文➋:range函数返回的0、1、2、3、4会依次赋给上下文中的变量x。

表达式➊:把从上下文中传过来的xy组合成一个元组。

上下文➋:上下文变量x的值会从range函数返回的(0,1,2)中进行迭代,而上下文变量y也会从range函数返回的(0,1,2)中迭代。这两个循环是嵌套的,对于x的每一个值,y都会重复一遍迭代过程,因此这两个上下文变量会有3×3=9种组合。

表达式➊:会对上下文变量x进行平方计算。

上下文➋:上下文变量x会遍历range函数的所有返回值——0、1、2、3、4、5、6、7、8、9——里面奇数的部分,即满足x%2>0的值。

表达式➊:会对上下文变量x执行字符串的小写转换函数。

上下文➋:上下文变量x会遍历列表中的每个字符串:'I'、'AM'、'NOT'、'SHOUTING'。

现在,你可以理解下面的代码了。

代码

考虑前面介绍过的员工工资问题:对于给定的一个包含字符串键和对应整数值的字典,创建一个由元组组成的列表,其中每个与键相关联的值都大于或等于10万。清单2-1展示了这个代码。

清单2-1:使用列表解析的一行流解决方案

这段代码的输出结果是什么呢?

它是如何工作的

我们来看看这句一行流代码:

表达式➊:对于每一组上下文变量k,v,创建一个简单的(k,v)键值对元组。

上下文➋:字典方法dict.items()确保上下文变量k会遍历这个字典所有的键,同时上下文变量v会遍历对应的值。不过if条件保证了只有当值大于或等于10万的时候,才会被遍历到。

这行代码的结果如下所示:

这个简单的一行流程序介绍了列表解析这一重要概念。我们在本书中会多次用到列表解析,所以在继续学习之前,请确保理解了本节中的例子。