I am trying to apply a function to all combinations of lists. I am trying to avoid using for
loops as in the program I am trying to write I would end up with 5 or more nested loops. One suggestion I had was to use the map() function, but I don't seem to be able to make it work.
Some examples:
For the sake of simplicity, I have a function which removes a hyphen from a string, and adds some suffix on the end of the string:
def changeString(item, suffix):
foo = item.replace("-", "")
bar = foo + suffix
return bar
items = ["Hel-lo", "Wor-ld", "-test-"]
suffixes = ["41", "2", "5"]
To achieve my desired behaviour, I can use:
foobar = []
for item in items:
for suffix in suffixes:
foobar.append(changeString(item, suffix))
which gives the output:
['Hello41', 'Hello2', 'Hello5', 'World41', 'World2', 'World5', 'test41', 'test2', 'test5']
This is the output I want, but I don't want to keep nesting loops like this.
I have tried to use map() to avoid nesting for
loops, which looks like this:
foobar = list( map( changeString, items, suffixes ) )
But this gives the wrong output:
['Hello41', 'World2', 'test5']
I have also attempted to use itertools.product
as such:
lst = [items, suffixes]
foobar = list(itertools.product(*lst))
but this gives the output:
[('Hel-lo', '41'), ('Hel-lo', '2'), ('Hel-lo', '5'), ('Wor-ld', '41'), ('Wor-ld', '2'), ('Wor-ld', '5'), ('-test-', '41'), ('-test-', '2'), ('-test-', '5')]
which to me seems like I have to use more loops to allow it be to be used by the function I defined above.
What is the most efficient way to apply my function to every possible combination of strings, while avoiding nesting for
loops over and over?
Have you tried applying changeString
in a list comprehension over each product?
from itertools import product
[changeString(*p) for p in product(items, suffixes)]
# ['Hello41', 'Hello2', 'Hello5', 'World41', ..., 'test2', 'test5']
Or, for better readability,
[changeString(item, suffix) for (item, suffix) in product(items, suffixes)]
# ['Hello41', 'Hello2', 'Hello5', 'World41', ..., 'test2', 'test5']