Reputation: 4706
I have a list of tuples, which in turn consist of two lists again. For example:
big_list = [
(["A", "B", "C"], [1, 2]),
(["X", "Y"], [9, 8, 7]),
]
I'd like to call some function on each combination of (letter, number). I currently have a big ugly set of three nested for loops, along these lines:
for (letters, numbers) in big_list:
for letter in letters:
for number in numbers:
do_stuff(letter, number)
That is, I'd like do_stuff
to be called once, for each combination of (letter, number) present in my list.
Is it feasible to collapse these three loops into one or two? Preferably in a way that isn't ugly and unPythonic?
Upvotes: 4
Views: 97
Reputation: 82899
You could also combine itertools.product
with starmap
and chain.from_iterable
:
from itertools import chain, starmap, product
for l, n in chain.from_iterable(starmap(product, big_list)):
print(l, n)
Of course, whether that's more clear is a matter of opinion. Or just use a generator expression:
for l, n in (p for ls, ns in big_list for p in product(ls, ns)):
print(l ,n)
Both ways, the result (as list
) is [('A', 1), ('A', 2), ('B', 1), ('B', 2), ('C', 1), ('C', 2), ('X', 9), ('X', 8), ('X', 7), ('Y', 9), ('Y', 8), ('Y', 7)]
.
Upvotes: 1
Reputation: 2321
I think itertools
may help:
import itertools
for (letters, numbers) in big_list:
for (letter, number) in itertools.product(letters, numbers):
do_stuff(letter, number)
This saves you a loop, so now you only have one nested loop to deal with. And I think it's bit more Pythonic.
Upvotes: 3