0

Issue

When I dereference an itertools.product object, I can't use it again.

Why?

Description

I created a generator function which can take an arbitrary set of keys: values and return all possible combinations of those values, or use the default values for the object. For testing, I printed the dereferenced itertools.product object, which then makes it unavailable for the rest of the function.

The generator no longer yields any objects.

Everything works perfect if I don't dereference the itertools.product object

Code

from pydantic import BaseModel
from itertools import product


class test_class(BaseModel):
    x = 0
    y = 0
    z = 1


def generate_objects(**kwargs):

    keys = kwargs.keys()
    vals = product(*(kwargs[key] for key in kwargs))
    
    # ------------------------------
    # print(*vals) 
    # this print statement will make the function yield nothing
    
    for val in vals:
        new_dict = {k:v for k, v in zip(keys, val)}

        yield test_class(**new_dict)


obj_generator = generate_objects(x=[2, 3, 4, 5], y=[1, 2], z=[1])

for obj in obj_generator:
    print(obj)

Output

If I don't print(*vals)

x=2 y=1 z=1
x=2 y=2 z=1
x=3 y=1 z=1
x=3 y=2 z=1
x=4 y=1 z=1
x=4 y=2 z=1
x=5 y=1 z=1
x=5 y=2 z=1

If I print(*vals)

(2, 1, 1) (2, 2, 1) (3, 1, 1) (3, 2, 1) (4, 1, 1) (4, 2, 1) (5, 1, 1) (5, 2, 1)
John Mansell
  • 624
  • 5
  • 16
  • 1
    Because a generator is just an object that implements the iterator protocol which doesn't support any sort of "restart" command. See [What exactly is Python's iterator protocol?](https://stackoverflow.com/questions/16301253/what-exactly-is-pythons-iterator-protocol). – martineau Jan 05 '22 at 05:06
  • 2
    Very import to understand, Python is not C, it doesn't have pointers, and that isn't dereferencing. That is *iterable unpacking*. The `product` object is an iterator, which can only.be iterated over once – juanpa.arrivillaga Jan 05 '22 at 05:08
  • 1
    @juanpa.arrivillaga You're right. I come from a C, C++ background and that's still how I think. Good to know iterator objects work differently. Thanks. – John Mansell Jan 05 '22 at 05:30

0 Answers0