高级嵌套列表理解语法

我一直在与列表理解打交道,以更好地理解它们,但遇到了一些我无法解释的意外输出。我之前没有发现这个问题,但是,如果它是重复的问题,我深表歉意。


我本质上是想写一个生成器。一个使用列表推导的简单生成器如下所示:


(x for x in range(10) if x%2==0) # generates all even integers in range(10)

我想要做的是编写一个生成器,生成两个生成器-第一个生成器生成range(10)中的偶数,第二个生成range(10)中的奇数。为此,我做了:


>>> (x for x in range(10) if x%2==i for i in range(2))

<generator object <genexpr> at 0x7f6b90948f00>


>>> for i in g.next(): print i

... 

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "<stdin>", line 1, in <genexpr>

UnboundLocalError: local variable 'i' referenced before assignment

>>> g.next()

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

StopIteration

>>> g = (x for x in range(10) if x%2==i for i in range(2))

>>> g

<generator object <genexpr> at 0x7f6b90969730>


我不明白为什么在分配之前会引用“ i”


我认为它可能与有关i in range(2),所以我做到了:


>>> g = (x for x in range(10) if x%2==i for i in [0.1])

>>> g

<generator object <genexpr> at 0x7f6b90948f00>

>>> g.next()

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "<stdin>", line 1, in <genexpr>

UnboundLocalError: local variable 'i' referenced before assignment

这对我来说没有意义,所以我认为最好先尝试一些简单的方法。因此,我返回列表并尝试:


>>> [x for x in range(10) if x%2==i for i in range(2)]

[1, 1, 3, 3, 5, 5, 7, 7, 9, 9]

我期望与以下相同:


>>> l = []

>>> for i in range(2):

...     for x in range(10):

...             if x%2==i:

...                     l.append(x)

... 

>>> l

[0, 2, 4, 6, 8, 1, 3, 5, 7, 9] # so where is my list comprehension malformed?

但是,当我直觉尝试时,它起作用了:


>>> [[x for x in range(10) if x%2==i] for i in range(2)]

[[0, 2, 4, 6, 8], [1, 3, 5, 7, 9]] # so nested lists in nested list comprehension somehow affect the scope of if statements? :S

因此,我认为该if语句在什么范围的范围内运行可能是一个问题。因此,我尝试了以下操作:


>>> [x for x in range(10) for i in range(2) if x%2==i]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

现在,我感到非常困惑。有人可以解释这种现象。我不明白为什么列表理解似乎不正确,也不了解if语句范围界定的工作原理。



慕的地6264312
浏览 429回答 3
3回答

LEATH

您需要使用一些括号:((x for x in range(10) if x%2==i) for i in range(2))这对我来说没有意义,所以我认为最好先尝试一些简单的方法。因此,我返回列表并尝试:[>>> [x对于范围(2)中的i,如果x%2 == i,则x对于范围(10)中的x] [1、1、3、3、3、5、5、7、7、9、9]之所以有效,是因为先前的列表理解将i变量泄漏到了封闭范围,并成为当前变量的i。尝试启动一个新的python解释器,由于NameError失败,这将失败。计数器的泄漏行为已在Python 3中删除。编辑:等效于for的循环:(x for x in range(10) if x%2==i for i in range(2))将会:l = []for x in range(10):&nbsp; &nbsp; if x%2 == i:&nbsp; &nbsp; &nbsp; &nbsp; for i in range(2):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; l.append(x)这也会给出名称错误。编辑2:括号中的版本:((x for x in range(10) if x%2==i) for i in range(2))等效于:li = []for i in range(2):&nbsp; &nbsp; lx = []&nbsp; &nbsp; for x in range(10):&nbsp; &nbsp; &nbsp; &nbsp; if x%2==i:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lx.append(x)&nbsp; &nbsp; li.append(lx)

人到中年有点甜

Lie Ryan的for循环等效项将我带到以下内容,这似乎确实可以正常工作:[x for i in range(2) for x in range(10) if i == x%2]输出[0, 2, 4, 6, 8, 1, 3, 5, 7, 9]Lie Ryan的for循环等效项将我带到以下内容,这似乎确实可以正常工作:[x for i in range(2) for x in range(10) if i == x%2]输出[0, 2, 4, 6, 8, 1, 3, 5, 7, 9]

青春有我

扩大李·瑞安的答案:某物=(如果x%2 == i对于范围(2)中的i,则x对于范围(10)中的x)等效于:def _gen1():&nbsp; &nbsp; for x in range(10):&nbsp; &nbsp; &nbsp; &nbsp; if x%2 == i:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for i in range(2):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; yield xsomething = _gen1()而带括号的版本等效于:def _gen1():&nbsp; &nbsp; def _gen2():&nbsp; &nbsp; &nbsp; &nbsp; for x in range(10):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if x%2 == i:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; yield x&nbsp; &nbsp; for i in range(2):&nbsp; &nbsp; &nbsp; &nbsp; yield _gen2()something = _gen1()实际上,这确实产生了两个生成器:[<generator object <genexpr> at 0x02A0A968>, <generator object <genexpr> at 0x02A0A990>]不幸的是,它产生的生成器有些不稳定,因为输出将取决于您如何使用它们:>>> gens = ((x for x in range(10) if x%2==i) for i in range(2))>>> for g in gens:&nbsp; &nbsp; &nbsp; &nbsp; print(list(g))[0, 2, 4, 6, 8][1, 3, 5, 7, 9]>>> gens = ((x for x in range(10) if x%2==i) for i in range(2))>>> for g in list(gens):&nbsp; &nbsp; &nbsp; &nbsp; print(list(g))[1, 3, 5, 7, 9][1, 3, 5, 7, 9]我的建议是完全写出生成器函数:我认为,如果i不这样做就试图获得正确的作用域几乎是不可能的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python