首页 > 解决方案 > 使用 map() 将函数应用于两个列表的所有组合

问题描述

我正在尝试将函数应用于列表的所有组合。我试图避免for在我试图编写的程序中使用循环,我最终会得到 5 个或更多嵌套循环。我的一个建议是使用 map() 函数,但我似乎无法使其工作。

一些例子:

为了简单起见,我有一个函数可以从字符串中删除连字符,并在字符串末尾添加一些后缀:

def changeString(item, suffix):
    foo = item.replace("-", "")
    bar = foo + suffix
    return bar

items = ["Hel-lo", "Wor-ld", "-test-"]
suffixes = ["41", "2", "5"]

为了实现我想要的行为,我可以使用:

foobar = []
for item in items:
    for suffix in suffixes:
        foobar.append(changeString(item, suffix))

这给出了输出:

['Hello41', 'Hello2', 'Hello5', 'World41', 'World2', 'World5', 'test41', 'test2', 'test5']

这是我想要的输出,但我不想保持这样的嵌套循环。

我尝试使用 map() 来避免嵌套for循环,如下所示:

foobar = list( map( changeString, items, suffixes ) )

但这给出了错误的输出:

['Hello41', 'World2', 'test5']

我也尝试itertools.product过这样使用:

lst = [items, suffixes]
foobar = list(itertools.product(*lst))

但这给出了输出:

[('Hel-lo', '41'), ('Hel-lo', '2'), ('Hel-lo', '5'), ('Wor-ld', '41'), ('Wor-ld', '2'), ('Wor-ld', '5'), ('-test-', '41'), ('-test-', '2'), ('-test-', '5')]

在我看来,我必须使用更多循环才能让我上面定义的函数使用它。

将我的函数应用于每个可能的字符串组合,同时避免for一遍又一遍地嵌套循环的最有效方法是什么?

标签: pythonitertools

解决方案


您是否尝试changeString过对每个产品进行列表理解?

from itertools import product

[changeString(*p) for p in product(items, suffixes)]
# ['Hello41', 'Hello2', 'Hello5', 'World41', ..., 'test2', 'test5']

或者,为了更好的可读性,

[changeString(item, suffix) for (item, suffix) in product(items, suffixes)]
# ['Hello41', 'Hello2', 'Hello5', 'World41', ..., 'test2', 'test5']

推荐阅读