python列表推导式:利用其它列表创建新列表的方法。
一、列表推导式语法
List comprehension的规则,称为listmaker。listmaker分为2种,最简单的一种,如下:
a = [1, 2, 3, 4, 5]
也就是直接列出List中的所有元素。这种方式最简单,也最好理解。
第二种就是本文所说的List Comprehension了,语法如下:
1、listmaker: test list_for 2、list_for: for 'explist 'in' testlist_safe [list_iter] 3、list_iter: list_for | list_if 4、list_if: if' old_test [list_iter]
语法文件全是正则表达式,而且前后相互引用,读起来非常吃力。不过在上面所列的这4行语法规则中,可以看到:list comprehension中,只能使用for和if这2种语句。
而且可以从上面的语法中看出,每个for语句后面,还可以接一个for语句或者一个if语句;每个if语句后面,也可以接一个for语句或者一个if语句;并且没有对for语句、if语句的个数有任何限制。
列表推导式书写形式:
[表达式 for 变量 in 列表] 或者 [表达式 for 变量 in 列表 if 条件]
举例:
li = [1,2,3,4,5,6,7,8,9] print [x**2 for x in li] print [x**2 for x in li if x>5] print dict([(x,x*10) for x in li])
二、列表推导式中for语句和if语句关系
Python的List Comprehension中,可以使用无限多个for、if语句,该怎么去理解这些for、if语句呢?它们之间的关系是什么呢?
Python的语法解析、字节码生成,大约分为3个阶段:
1、将.py源代码,解析成语法树 2、将语法树,解析成AST树 3、根据AST树,生成字节码
对于List Comprehension,可以在第2阶段,即Python/Ast.c这个源文件中,发现for语句和if语句之间的关系。
Python在从语法树生成AST的过程中,会将List Comprehension中的for分离开来,并将每个if语句,全部归属于离他最近的左边的for语句,例如
a = [ (x, y) for x in range(10) if x % 2 if x > 3 for y in range(10) if y > 7 if y != 8 ]
上面这段代码中,有2个for和4个if,分别如下:
1、for x in range(10) 2、for y in range(10) 3、if x % 2 4、if x > 3 5、if y > 7 6、if y != 8
在AST的过程中,Python会按照for语句将上面的语句拆成2部分,分别如下:
每个if语句,从属于离他最近的左边的for语句。
下面看语法解析的第三阶段,即:通过AST生成字节码,在源代码Python/Compiler.c文件中。
在Python/Compiler.c源文件中,处理List Comprehension的代码,主要是2592行的compiler_listcomp_generator(…)函数。
这个函数,首先会生成字节码:BUILD_LIST,即生成一个新的List;然后通过自身的递归,从左到右,依次处理AST过程生成的for语句及其从属的if语句。
从上面可以看出列表推导式是从左到右的,如代码:
a = [ (x, y) for x in range(2) for y in range(3) ]
写成伪代码是:
for x in range(10): for y in range(10: a.append((x, y))
而不是
for y in range(10): for x in range(10): a.append((x, y))
三、列表推导式与if-expr语句
在python中存在类似C语言中三元运算符 ?: 的语法,称为if-expr语句,语句形式如下:
a = 5 if b > 3 else 2
由于if-expr语句容易和列表推导式的语法冲突,导致在列表推导式中不能使用if-expr语句。
四、列表推导式中变量
一个简单的例子:
a = [ x for x in range(10) ]
这里面的变量x,是局部变量吗?在列表推导式结束后,还可以访问变量x吗?
可以看到当列表推导式结束后,可以访问变量x。
参考资料:http://blog.chinaunix.net/uid-28631822-id-3488324.html
转载请注明:jinglingshu的博客 » python列表推导式