使用列表推导在列表中查找1个元素?

时间:2019-03-05 14:15:22

标签: python list-comprehension

我有一个关于Python最佳做法的快速问题。我已经了解了在列表理解中使用了lambda +过滤器函数的地方,但是我想知道是否存在一种更简单的方法来查找列表中的特定元素,而无需在整个列表中生成和迭代。

使用AWS boto3库,我正在使用列表推导查询各种get_x()函数:

[i['domainName'] for i in domain_names['items'] if re.search(r'\b'+domain_name, i['domainName'])].pop()

[i['id'] for i in usage_plans['items'] if i['name']==f'{self.service}Usage'].pop()

如果未找到任何项目,则将捕获IndexError并将其中继回用户。由于它在AWS Lambda函数中,因此我担心该函数的可伸缩性和运行时计费。

我应该继续使用列表理解方法还是有更好的方法?

1 个答案:

答案 0 :(得分:4)

如果要避免遍历整个列表,则可以使用生成器理解而不是列表理解。例如:

next(i for i in range(0, 2**1000) if i % 2 == 1)

在整个范围内进行迭代将花费一些时间,但是使用生成器理解是瞬时的。

请注意,如果找不到项目,则会得到StopIteration而不是IndexError例外。您确实必须捕获该错误并将其包装在另一个异常中,因为在堆栈中传播的流浪StopIteration可能会导致奇怪的行为。

包装StopIteration如下:

>>> try:
...   next(i for i in range(0, 100) if i % 2 == 3 )
... except StopIteration:
...   raise IndexError("Couldn't find item")
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
IndexError: Couldn't find item

请注意,您可以给next提供默认值以返回而不是提高StopIteration

>>> print(next((i for i in range(0, 100) if i % 2 == 3), None))
None