Skip to main content
 首页 » 编程设计

python之如何应用函数式编程去除两个嵌套的for i in

2025年05月04日15www_RR

最初我有一段糟糕的代码,里面有两个 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关键字和生成器

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 

但是生成器真的很棒,你会看到它们有多强大。