python-不带赋值的列表理解

2024-04-26 20:43:48 发布

您现在位置:Python中文网/ 问答频道 /正文

今天,我正在分析一个目录索引,其中列出了使用BeautifulSoup压缩文件的路径列表,我发现了一件有趣的事情。假设我想获取所有标签的href属性,并将它们直接放入队列中:

q = Queue.Queue()
[q.put(tag['href']) for tag in soup.findAll('a')]

我以前从未遇到过这样的情况,在这种情况下,一个理解可以内联使用,而无需将它赋给任何东西,只需通过一些例程调用生成另一个迭代器。这被认为是不好的做法吗?它本身就是“Python”吗?有没有更好的班轮把所有的东西都排成一列?


Tags: 路径列表for属性队列queueputtag
3条回答

这个问题已经问过很多次了,例如herehere。不过,这是个有趣的问题。列表理解是用来做其他事情的。

其他选项包括

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

而简单的循环是最好的方法。在本例中,它在语义上是正确的,所有其他方式,包括列表理解,滥用概念的副作用。

在Python 3.x中,map()filter()是生成器,因此在迭代之前什么也不做。所以我们需要,例如,一个list(map(...)),这会使情况更糟。

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

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

>>> import Queue
>>> q = Queue.Queue()
>>> [q.put(item) for item in range(5)]
[None, None, None, None, None]
>>>

这个未使用的清单显然是浪费。因此,这个结构,一个带有未使用返回值的列表理解,被禁止出现在我们的代码库中。上面这样的显式循环,或者生成的循环与消耗它的内容组合在一起,例如:

>>> any(q.put(item) for item in xrange(5))
False
>>>

或者只是:

>>> for item in xrange(5):
...     q.put(item)
...
>>>

必须通过审查。

如果您将其视为soup.findAll返回的列表上的循环,它将如下所示:

for tag in soup.findAll('a'):
    q.put(tag['href'])

这可能是更“pythonic”的形式,因为“显式优于隐式”

相关问题 更多 >