Python 列表推导式与字典推导式的实现
在 Python 中推导式是一种非常 Pythonic 的知识本篇博客将为你详细解答列表推导式与字典推导式相关的技术知识。列表推导式列表推导式可以利用列表元组字典集合等数据类型快速的生成一个特定需要的列表。语法格式如下[表达式 for 迭代变量 in 可迭代对象 [if 条件表达式]]if 条件表达式 非必选学完列表推导式之后你可以发现它就是 for 循环的一个变种语句例如咱们现有一个需求是将一个列表中的所有元素都变成原值的 2 倍。for 循环写法123456my_list[1,2,3]new_list[]foriinmy_list:new_list.append(i*2)print(new_list)列表推导式写法12nn_list[i*2foriinmy_list]print(nn_list)是不是对比看就是将 for 循环语句做了变形之后增加了一个 []不过需要注意的是列表推导式最终会将得到的各个结果组成一个新的列表。再看一下列表推导式语法构成 nn_list [i*2 for i in my_list] for 关键字后面就是一个普通的循环前面的表达式 i*2 其中的 i 就是 for 循环中的变量也就是说表达式可以用后面 for 循环迭代产生的变量理解这个内容列表推导式就已经掌握 9 成内容了剩下的是熟练度的问题。在将 if 语句包含进代码中运行之后你也能掌握基本技巧if 语句是一个判断其中 i 也是前面循环产生的迭代变量。12nn_list[i*2foriinmy_listifi1]print(nn_list)这些都是一般技能列表推导式能支持两层 for 循环例如下述代码12nn_list[(x,y)forxinrange(3)foryinrange(3) ]print(nn_list)当然如果你想**加密谁都看不懂你的代码**你的代码你可以无限套娃下去列表推导式并没有限制循环层数多层循环就是一层一层的嵌套你可以展开一个三层的列表推导式就都明白了12nn_list[(x,y,z,m)forxinrange(3)foryinrange(3)forzinrange(3)forminrange(3)]print(nn_list)当然在多层列表推导式里面依旧支持 if 语句并且 if 后面可以用前面所有迭代产生的变量不过不建议超过 2 成超过之后会大幅度降低你代码的可阅读性。当然如果你希望你代码更加难读下面的写法都是正确的。123456nn_list[(x, y, z, m)forxinrange(3)ifx 1foryinrange(3)ify 1forzinrange(3)forminrange(3)]print(nn_list)nn_list[(x, y, z, m)forxinrange(3)foryinrange(3)forzinrange(3)forminrange(3)ifx 1andy 1]print(nn_list)nn_list[(x, y, z, m)forxinrange(3)foryinrange(3)forzinrange(3)forminrange(3)ifx 1ify 1]print(nn_list)现在你已经对列表推导式有比较直观的概念了列表推导式对应的英文是 list comprehension有的地方写作列表解析式基于它最后的结果它是一种创建列表的语法并且是很简洁的语法。有了两种不同的写法那咱们必须要对比一下效率经测试小数据范围影响不大当循环次数到千万级时候出现了一些差异。123456789101112importtimedefdemo1():new_list[]foriinrange(10000000):new_list.append(i*2)defdemo2():new_list[i*2foriinrange(10000000)]s_timetime.perf_counter()demo2()e_timetime.perf_counter()print(代码运行时间, e_time-s_time)运行结果# for 循环代码运行时间 1.3431036140000001# 列表推导式代码运行时间 0.9749278849999999在 Python3 中列表推导式具备局部作用域表达式内部的变量和赋值只在局部起作用表达式的上下文里的同名变量还可以被正常引用局部变量并不会影响到它们。所以其不会有变量泄漏的问题。例如下述代码12345x6my_var[x*2forxinrange(3)]print(my_var)print(x)列表推导式还支持嵌套参考代码如下只有想不到没有做不到的。12my_var[y*4foryin[x*2forxinrange(3)]]print(my_var)字典推导式有了列表推导式的概念字典推导式学起来就非常简单了语法格式如下{键:值 for 迭代变量 in 可迭代对象 [if 条件表达式]}直接看案例即可12my_dict{key: valueforkeyinrange(3)forvalueinrange(2)}print(my_dict)得到的结果如下{0: 1, 1: 1, 2: 1}此时需要注意的是字典中不能出现同名的 key第二次出现就把第一个值覆盖掉了所以得到的 value 都是 1。最常见的哪里还是下述的代码遍历一个具有键值关系的可迭代对象。123my_tuple_list[(name,橡皮擦), (age,18),(class,no1), (like,python)]my_dict{key: valueforkey, valueinmy_tuple_list}print(my_dict)元组推导式与集合推导式其实你应该能猜到在 Python 中是具备这两种推导式的而且语法相信你已经掌握了。不过语法虽然差不多但是元组推导式运行结果却不同具体如下。12my_tuple(iforiinrange(10))print(my_tuple)运行之后产生的结果generator object genexpr at 0x0000000001DE45E8使用元组推导式生成的结果并不是一个元组而是一个生成器对象需要特别注意下这种写法在有的地方会把它叫做生成器语法不叫做元组推导式。集合推导式也有一个需要注意的地方先看代码12my_set{valueforvalueinHelloWorld}print(my_set)因为集合是无序且不重复的所以会自动去掉重复的元素并且每次运行显示的顺序不一样使用的时候很容易晕掉。总结