python - 没有赋值的列表理解

Dea*_*ado 12 python list-comprehension

今天我正在解析一个目录索引,其中包含使用BeautifulSoup压缩文件的路径列表,并且遇到了一件有趣的事情.让我们假设我想获取href我得到的标签的所有属性并将它们直接放入队列中:

q = Queue.Queue()
[q.put(tag['href']) for tag in soup.findAll('a')]
Run Code Online (Sandbox Code Playgroud)

我从来没有碰到这样的情况,在此之前可以使用内联而不将其分配给任何东西,只是通过一些例程调用生成另一个迭代器.这被认为是不好的做法吗?它本身就是"pythonic"吗?是否有更好的单行将所有项目放入队列?

Tho*_*anz 12

这已被多次询问,例如,在这里这里.但这是一个有趣的问题.列表推导意味着用于其他事情.

其他选择包括

  1. 使用map()- 与您的样品基本相同
  2. use filter()- 如果你的函数返回None,你将得到一个空列表
  3. 只是一个简单的for循环

而普通循环是最好的方法.在这种情况下,它在语义上是正确的,所有其他方式,包括列表理解,滥用概念的副作用.

在Python 3.x中,map()并且filter()是发电机,因此什么也不做,直到你在它们之间迭代.所以我们需要,例如,a list(map(...)),这会使情况变得更糟.


tim*_*imc 6

如果你认为它是一个循环覆盖在汤.findAll返回的列表上,它将如下所示:

for tag in soup.findAll('a'):
    q.put(tag['href'])
Run Code Online (Sandbox Code Playgroud)

这可能是更"'pythonic'形式,因为'显性比暗示更好'


Sin*_*ion 6

关于这个线程有很多意见,我只能从我组织的编码约定中发言。

有很多方法可以影响循环,但列表推导式的一个关键属性是它们创建列表,在迭代序列中每个列表都有一个项目。

>>> import Queue
>>> q = Queue.Queue()
>>> [q.put(item) for item in range(5)]
[None, None, None, None, None]
>>>
Run Code Online (Sandbox Code Playgroud)

这个未使用的列表显然是浪费的。因此,这个结构是一个带有未使用返回值的列表推导式;禁止出现在我们的代码库中。像上面这样的显式循环,或者生成的与消耗它的东西相结合,例如:

>>> any(q.put(item) for item in xrange(5))
False
>>>
Run Code Online (Sandbox Code Playgroud)

要不就:

>>> for item in xrange(5):
...     q.put(item)
...
>>>
Run Code Online (Sandbox Code Playgroud)

需要通过审核。

  • 乍一看,“any()”技巧很有趣,但应该注意的是,“any()”一旦找到计算结果为“True”的项,就会停止遍历结构。例如,如果表达式“q.put(item)”在某个时刻返回真值,则处理将停止。当您使用“any()”想出一个万无一失的构造时,您会意识到最好只使用普通的“for ... in”。 (2认同)