最新消息:

python列表推导式

Python admin 2319浏览 0评论

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部分,分别如下:

jinglingshu_2014-12-15_08-38-50jinglingshu_2014-12-15_08-38-51

 

每个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吗?

QQ截图20141215173012

QQ截图20141215173240

可以看到当列表推导式结束后,可以访问变量x。

参考资料:http://blog.chinaunix.net/uid-28631822-id-3488324.html

转载请注明:jinglingshu的博客 » python列表推导式

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址