You'll need to establish an additional recursive case for len(ar_list) == 2. As stated previously in the comments, this works only when ar_list.__len__ is defined.
def product(ar_list):
if not ar_list:
yield ()
elif len(ar_list) == 2:
ar_list[0] = [x for x in ar_list[0] if x % 2 == 0]
ar_list[1] = [x for x in ar_list[1] if x % 2 == 0]
for a in ar_list[0]:
for prod in product(ar_list[1:]):
out = (a,) + prod
yield out
else:
for a in ar_list[0]:
for prod in product(ar_list[1:]):
out= (a,) + prod
yield out
Really, the simplest way is to filter the results of itertools.product and this solution works when ar_list.__len__ is not defined.
import itertools
def product(ar_list):
for prod in itertools.product(*ar_list):
if prod[-2] % 2 == 0 and prod[-1] % 2 == 0:
yield prod
A potentially more efficient solution is to filter prior to generating the Cartesian product but does require ar_list to be subscriptable.
import itertools
def product(ar_list):
ar_list[-2] = [x for x in ar_list[-2] if x % 2 == 0]
ar_list[-1] = [x for x in ar_list[-1] if x % 2 == 0]
for prod in itertools.product(*ar_list):
if prod[-2] % 2 == 0 and prod[-1] % 2 == 0:
yield prod
ar_listhas two elements or less, and if so, only yield elements whereprodis even. (i.e. yield ifar_listis longer than two elements, orprodis even.) This is not possible ifar_listis an iterator, as "reading the future" will exhaust it; in this case, you will either need to cheat by duping the iterable before counting the remaining elements, or — simpler — just filter (non-recursively) the results of this generator.[(1, 4, 6), (2, 4, 6)]? If not, please update your post with the expected output.