Python之列表推导式最全汇总(上篇)

前言 

网传的七天学Python的路线如下,我觉得可以在学过此表中前几天的内容后,就可以回头来学习一下

列表推导式:它综合了列表、for循环和条件语句。

第一天:基本概念(4小时) : print,变量,输入,条件语句。

第二天:基本概念(5小时) :列表,for循环,while循环,函数,导入模块。

第三天:简单编程问题(5小时) :交换两个变量值,将摄氏度转换为华氏温度,求数字中各位数之和, 判断某数是否为素数, 生成随机数,删除列表中的重复项等等。

第四天:中级编程问题(6小时) :反转-个字符串(回文检测),计算最大公约数,合并两个有序数组,猜数字游戏,计算年龄等等。

第五天:数据结构(6小时) :栈,队列,字典,元组,树,链表。

第六天:面向对象编程(OOP) (6小时) :对象,类,方法和构造函数,面向对象编程之继承。

第七天:算法(6小时) :搜索(线性和二分查找)、 排序(冒泡排序、 选择排序)、递归函数(阶乘、斐波那契数列)时间复杂度(线性、二次和常量)。

列表推导式

  • list comprehension或译为列表解析式,是一种创建列表的简洁语法;
  • 也可认为它是一个简版的for循环,但执行效率高于for循环。
  • python 2.7+ 开始又引入了集合推导式、字典推导式,原理与列表推导式相近。

语法规范:

out_list = [out_express for out_express in input_list if out_express_condition]

其中,

  • if 条件可有可无;
  • for 循环可以嵌套多层,内外层循环的变量不可以同名;
  • 推导式中也可以嵌套推导式,内外层推导式的变量互不影响,可以同名;
  • 推导表达式out_express尽可能用内置函数,省得import或def function()。

入门实例

>>> [i for i in range(20)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> [i for i in range(40) if i%2==0]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38]
>>> [i*2 for i in range(20)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38]
>>> [i+j for i in range(5) for j in range(5)]
[0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8]
>>> [i+j for i in range(10) for j in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6,
 7, 8, 9, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 4, 5, 6, 7, 8, 9, 10, 11,
 12, 13, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 6, 7, 8, 9, 10, 11, 12, 13, 14,
 15, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 17, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
>>> {i+j for i in range(10) for j in range(10)}
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}
>>> [(i,j,k) for i in 'abc' for j in range(2) for k in range(2)]
[('a', 0, 0), ('a', 0, 1), ('a', 1, 0), ('a', 1, 1), ('b', 0, 0), ('b', 0, 1),
 ('b', 1, 0), ('b', 1, 1), ('c', 0, 0), ('c', 0, 1), ('c', 1, 0), ('c', 1, 1)]
>>> [chr(i) for i in range(97,123)]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
>>> {i:ord(i) for i in [chr(i) for i in range(97,123)]}
{'a': 97, 'b': 98, 'c': 99, 'd': 100, 'e': 101, 'f': 102, 'g': 103, 'h': 104,
 'i': 105, 'j': 106, 'k': 107, 'l': 108, 'm': 109, 'n': 110, 'o': 111, 'p': 112,
 'q': 113, 'r': 114, 's': 115, 't': 116, 'u': 117, 'v': 118, 'w': 119, 'x': 120,
 'y': 121, 'z': 122}
>>> dic={i:ord(i) for i in [chr(i) for i in range(97,123)]}
>>> dic['x']
120
>>> 

注:

  • 列表推导式外用‘[...]’,换成‘{...}’就是集合推导式;有键值对就是字典推导式。
  • 推导式外用‘(...)’会得到一个“生成器”,如果需要“元组推导式”另要用tuple()函数转换;
  • 生成器还有一个特性,只能被遍历一次,遍历过后就会被清空。
>>> (i for i in range(20))
 at 0x0000000002CF3890>
>>> type(i for i in range(20))

>>> tuple(i for i in range(20))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
>>> 
>>> g = (i for i in range(10))
>>> g
 at 0x03CE71E8>
>>> a = [i for i in g]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> b = [i for i in g]
>>> b
[]
>>>

生成过程

>>> [i for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
#这个推导式用for循环赋值的代码:

my_list = []
for i in range(10):
    my_list.append(i)
print(my_list)

注:

  • 当然这么简单的列表,可以不用推导式更不需要写代码来生成。
  • python有更加省事的方法来直接赋值:

方法一:

>>> a = []; a[:] = range(10)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>

方法二

此方法是我在学习用星号“*”给序列解包时偶尔试出来的

>>> *a,=range(10)  # 此处变量a后的逗号“,”必不可少
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> 
>>> # 或者:
>>> a = [*range(10)]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> 
>>> # 若要取部分,把不要的元素“赋值”给下划线 _
>>> _,*a=range(10)
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> 
>>> # 元组的赋值,结尾用逗号:
>>> tp = *range(1,11),
>>> tp
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>>>

序列解包 * :

>>> Cards = [*range(2,10),*list('TJQKA')]
>>> Cards
[2, 3, 4, 5, 6, 7, 8, 9, 'T', 'J', 'Q', 'K', 'A']
>>> Cards = *range(2,10),*tuple('TJQKA')
>>> Cards
(2, 3, 4, 5, 6, 7, 8, 9, 'T', 'J', 'Q', 'K', 'A')
>>>  # tuple 赋值时连最外的()都可以省掉

map()函数解包 * 

>>> n = 12345678
>>> [int(i) for i in str(n)]
[1, 2, 3, 4, 5, 6, 7, 8]
>>> [*map(int,str(n))]
[1, 2, 3, 4, 5, 6, 7, 8]
>>> 

还有一个特别的:单循环的变量可用 _ 代替:

>>> [_ for _ in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [_*_ for _ in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [str(_) for _ in range(2,10)]
['2', '3', '4', '5', '6', '7', '8', '9']
>>> 

列表元素间的运算

# 加法
>>> listAdd = lambda a,b:[i+j for m,i in enumerate(a) for n,j in enumerate(b) if m==n]
>>> a = [1,2,3,4]
>>> b = [2,4,7,11,16]
>>> listAdd(a,b)
[3, 6, 10, 15]
>>> listAdd([0]+a,b)
[2, 5, 9, 14, 20]
>>> listAdd(a,b[1:])
[5, 9, 14, 20]
>>> listAdd(a[1:],b)
[4, 7, 11]
>>> 
# 其它运算
>>> listOP = lambda a,b,c=0:[i-j if c==2 else i*j if c==3 else i/j if c==4 else i//j if c==5 else i%j if c==6 else i+j for m,i in enumerate(a) for n,j in enumerate(b) if m==n]
>>> a = [1,2,3,4]
>>> b = [2,4,7,11,16]
>>> listOP(a,b)
[3, 6, 10, 15]
>>> listOP(a,b,1)
[3, 6, 10, 15]
>>> listOP(a,b,2)
[-1, -2, -4, -7]
>>> listOP(b,a,2)
[1, 2, 4, 7]
>>> listOP(a,b,2)
[-1, -2, -4, -7]
>>> listOP(a,b,3)
[2, 8, 21, 44]
>>> listOP(a,b,4)
[0.5, 0.5, 0.42857142857142855, 0.36363636363636365]
>>> listOP(b,a,4)
[2.0, 2.0, 2.3333333333333335, 2.75]
>>> listOP(a,b,5)
[0, 0, 0, 0]
>>> listOP(b,a,5)
[2, 2, 2, 2]
>>> listOP(b[1:],a,5)
[4, 3, 3, 4]
>>> listOP(a,b,6)
[1, 2, 3, 4]
>>> listOP(b,a,6)
[0, 0, 1, 3]
>>> listOP(b[2:],a,6)
[0, 1, 1]
>>> 

附录

到此这篇关于Python之列表推导式最全汇总(上篇)的文章就介绍到这了,其他两个部分的内容(中、下篇)请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

你可能感兴趣的:(Python之列表推导式最全汇总(上篇))