Skip to content Skip to sidebar Skip to footer

How To 'flatten' Generators In Python?

I have a problem with 'flattening' out some generators in python. Here is my code: import itertools as it test = [[1,2,3],[4,5],[6,7,8]] def comb(possible): if len(possible) !=

Solution 1:

Here's one way to calculate a product of lists without using the built-in

def product (*iters):
  def loop (prod, first = [], *rest):
    if not rest:
      forxin first:
        yield prod + (x,)
    else:
      forxin first:
        yield from loop (prod + (x,), *rest)
  yield from loop ((), *iters)

forprodinproduct ("ab", "xyz"):
  print (prod)

# ('a', 'x')
# ('a', 'y')
# ('a', 'z')
# ('b', 'x')
# ('b', 'y')
# ('b', 'z')

In python, we can collect the outputs of a generator in a list by using the list constructor. Note we can also calculate the product of more than two inputs as seen below

print (list (product ("+-", "ab", "xyz")))
# [ ('+', 'a', 'x')# , ('+', 'a', 'y')# , ('+', 'a', 'z')# , ('+', 'b', 'x')# , ('+', 'b', 'y')# , ('+', 'b', 'z')# , ('-', 'a', 'x')# , ('-', 'a', 'y')# , ('-', 'a', 'z')# , ('-', 'b', 'x')# , ('-', 'b', 'y')# , ('-', 'b', 'z')# ]

Because product accepts a a list of iterables, any iterable input can be used in the product. They can even be mixed as demonstrated below

print (list (product (['@', '%'], range (2), "xy")))
# [ ('@', 0, 'x')# , ('@', 0, 'y')# , ('@', 1, 'x')# , ('@', 1, 'y')# , ('%', 0, 'x')# , ('%', 0, 'y')# , ('%', 1, 'x')# , ('%', 1, 'y')# ]

Because product is defined as a generator, we are afforded much flexibility even when writing more complex programs. Consider this program that finds right triangles made up whole numbers, a Pythagorean triple. Also note that product allows you to repeat an iterable as input as see in product (r, r, r) below

def is_triple (prod):(a,b,c)=prodreturn a * a + b * b ==c*c

def solver (n):
  r =range(1,n)for p in product (r, r, r):if is_triple (p):
      yield p

print (list(solution in solver (20)))# (3, 4, 5)# (4, 3, 5)# (5, 12, 13)# (6, 8, 10)# (8, 6, 10)# (8, 15, 17)# (9, 12, 15)# (12, 5, 13)# (12, 9, 15)# (15, 8, 17)

For additional explanation and a way to see how to do this without using generators, view this answer.

Post a Comment for "How To 'flatten' Generators In Python?"