最初我有一段糟糕的代码,里面有两个 for i。总而言之,我的想法是获取一些带有特定标签的 AMIS 的 AMI ID 列表。为此,我遍历列表(错误!)并获得 IDS 列表。
def aws_get_images_exceptions(connection, exceptions):
list_exceptions = []
for ex in exceptions:
images = connection.get_all_images(filters={ "tag-key":"Name","tag-value":ex})
for ami in images:
list_exceptions.append(ami.id)
return list_exceptions
在每次迭代中,我都会根据我提供给函数的固定标签 Role 获得“异常”的完整列表,然后附加正确的 AMIS。
好的,我可以使用下一个代码删除第二个 for i:
def aws_get_images_exceptions(connection, exceptions):
for ex in exceptions:
images = connection.get_all_images(filters={ "tag-key":"Name","tag-value":ex})
list_exceptions = list(map(lambda x: x.id, images)) + list_exceptions
return list_exceptions
我已经检查过,我得到了相同数量的 AMIS、相同的 IDS 等。但是我没有找到以功能方式删除第一个 for 的方法。正如您所注意到的,我手动调用了 get_all_images,因为我遍历了我提供给该函数的“异常”列表。
你知道我如何先删除它吗?
感谢大家!
请您参考如下方法:
你不需要删除 for 循环(尤其是 lambdas)因为它是正常的并且足够可读, 然而,最好使用 generator 将图像提取提取到单独的函数中。
def get_images(connection, exceptions):
for ex in exceptions:
images = connection.get_all_images(filters={"tag-key": "Name", "tag-value": ex})
# in Python 3.3+ instead of loop use
# yield from images
for image in images:
yield image
然后初始函数将是
def aws_get_images_exceptions(connection, exceptions):
images = get_images(connection, exceptions)
return [ami.id for ami in images]
而且我认为它不能完全以函数式方式编写,因为看起来您正在调用某种数据库(这是一个 side effect)
进一步阅读
关于yield关键字和生成器
- docs ,
- PEP-255其中引入了
yield关键字, - epic Stack Overflow thread .
P. S.
get_images 也可以不使用生成器重写
def get_images(connection, exceptions):
images = []
for ex in exceptions:
images += connection.get_all_images(filters={"tag-key": "Name", "tag-value": ex})
return images
但是生成器真的很棒,你会看到它们有多强大。
