Set interpolation not working

I have here what I expect to get the output

set(), set(set()), set(set(set()))`

import itertools

def interpolate_sets():
    a = set()
    for i in itertools.count():
        a = set(a)
        yield [a] * i

interpolator = interpolate_sets()
for _ in range(3):
    print(next(interpolator))

But it seems to be ignoring my prompt:

a = set(a)

What’s going on? How can I fix it?

In [1]: set(set())
Out[1]: set()

In [2]: {set()}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[2], line 1
----> 1 {set()}

TypeError: unhashable type: 'set'

set() creates a set, which is iterable. set(iterable) produces a set containing the contents of the iterable. So set(set()) is just a slightly slower way of saying set(). Now, if you actually want to put a set in a set, you’ll fail, because sets have to be able to hash their contents, and a set is not hashable. You would need a frozen set for that.

1 Like

So that’s the problem…

How can I fix it?

It’s not broken. You are getting set(), set(set()) and set(set(set())), which just all happen to evaluate to set(). You cannot get set([set()]). You can do frozenset([frozenset()]) if you like. (Built-in Types — Python 3.12.1 documentation)

Let’s have an example

An example of what?

??

Of interpolated sets using the frozenset() method

Chris already gave you one? Try it:

I’m sorry but how can apply a = frozenset(a) to this?

import itertools

def interpolate_sets():
    a = frozenset()
    for i in itertools.count():
        a = frozenset(a)
        yield a

# Example usage
interpolator = interpolate_sets()
for _ in range(5):
    print(next(interpolator))

Isn’t working

I realize I can’t change the set once it’s established, so how do I put the sets together?

Look more closely at what Chris wrote.

You need a = frozenset([a]).

1 Like

Oh $&@! It worked

Thank you peeps!

You’ve got this:

 a = set(a)

The set() constructor takes an iterable, so this returns a new set
with the same elements as in a. So set()set().

I suspect you want this:

 a = set([a])

i.e. a 1-element set whose elements come from [a] i.e. a 1-list
containing the set a.

Your first incantation makes a set containing the elements of a.
The incantation above makes a set whose sole element is a itself
(the elements of the list [a]).