I have a generator, and I'd like to perform a nested loop on it in such a way that the inner loop will start from where the outer loop stands at the moment. For example, I have a generator that produces the list [1,2,3]
, and my loop should produce: (1,2),(1,3),(2,3)
. The code I came up with is the following:
from itertools import tee
def my_gen():
my_list = [1, 2, 3]
for x in my_list:
yield x
first_it = my_gen()
while True:
try:
a = next(first_it)
first_it, second_it = tee(first_it)
for b in second_it:
print(a,b)
except StopIteration:
break
This code is cumbersome, not efficient and does not look very pythonic to me. Please notice that I cannot use combinations_with_replacement
because I need an inner loop for processing a specific value from the outer loop.
Any suggestions for a more elegant and pythonic code?
The repeated cloning and exhausting of only one of the resulting iterators is not very efficient. As per the itertools.tee
docs :
In general, if one iterator uses most or all of the data before another iterator starts, it is faster to use list() instead of tee().
from itertools import islice
my_list = [1, 2, 3]
# or, more generally
# my_list = list(my_gen())
for i, a in enumerate(my_list):
for b in islice(my_list, i+1, None):
print((a, b))
(1, 2)
(1, 3)
(2, 3)
The result (1,2),(1,3),(2,3)
isn't the cartesian product. Do you mean to obtain all the combinations without repetition?
For combinations without repetition
Use itertools.combinations
function:
from itertools import combinations
print(list(combinations([1,2,3], 2)))
For actual cartesian product
Using list comprehension you can reduce your code into a more pythonic and elegant way:
my_list = [1, 2, 3]
c_prod = [(i, j) for i in iter(my_list) for j in iter(my_list)]
print(c_prod)
Another choice is to use the itertools.product
function:
import itertools
for i in itertools.product(my_list, my_list):
print(i)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.