Tho*_*lor 1 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 函数中,我担心该函数的可扩展性和运行时计费。
我应该继续按照我的方式使用列表理解,还是有更好的方法?
如果你想避免遍历整个列表,你可以使用生成器推导而不是列表推导。例如:
next(i for i in range(0, 2**1000) if i % 2 == 1)
Run Code Online (Sandbox Code Playgroud)
遍历整个范围需要一段时间,但使用生成器理解它是即时的。
请注意,如果它没有找到一个项目,你会得到一个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
Run Code Online (Sandbox Code Playgroud)
请注意,您可以提供next一个默认值来 return 而不是 raise StopIteration:
>>> print(next((i for i in range(0, 100) if i % 2 == 3), None))
None
Run Code Online (Sandbox Code Playgroud)