2

From this link it says generators aren't initialized like iterables.

How do you add the elements of a generator to a set? Is there a better way than just a for item in generator sort of thing and using setname.add(item)?

The generator is that returned by a cursor.execute("SELECT ...") command to the cursor from a connection to an sqlite3 database.

Community
  • 1
  • 1
ehacinom
  • 8,070
  • 7
  • 43
  • 65

2 Answers2

7

You could use the update method:

In [3]: x = set()

In [4]: g = (i**2 for i in range(5))

In [6]: x.update(g)

In [7]: x
Out[7]: {0, 1, 4, 9, 16}

update modifies x. If you just want to return a new set you could use union:

In [8]: x = set()

In [9]: g = (i**2 for i in range(5))

In [10]: x.union(g)
Out[10]: {0, 1, 4, 9, 16}
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • 1
    is that actually different from `for i in g: x.add(i)` in this case? I think that's all `set.update` will do when given a generator, but it may be somehow optimized. – Adam Smith Aug 20 '14 at 18:35
  • 2
    @AdamSmith: After doing a %timeit test, it appears calling `update` once is slightly quicker than using a Python loop and calling `x.add` many times, but the difference is not very great for large generators. That makes sense since `set.update` is just on call implemented in C (at least in CPython), but under the hood, Python is still looping through the generator. – unutbu Aug 20 '14 at 18:39
  • You don't need the for inside update either. `my_set.update(my_generator())` works as well. – tdelaney Aug 20 '14 at 18:48
  • 1
    @tdelaney: My answer does not use `for` inside `update`. The `for` is simply to define a simple generator. – unutbu Aug 20 '14 at 18:50
  • @unutbu, sorry about that, i was saw list when i should have seen generator. – tdelaney Aug 20 '14 at 18:52
4

You could also just do set(gen):

>>> set(x**2 for x in range(5))
set([0, 1, 4, 9, 16])

(Note that this creates a new set with just the elements in the generator. You'll need to do something along the lines of unutbu's answer if you want to add the elements to a pre-existing set.)

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • Great answer, but if you just want to add the items from the generator, you don't even need the for: `set(my_generator())` will do. – tdelaney Aug 20 '14 at 18:46
  • @tdelaney: I just used a generator comprehension as an example of a generator. As I said at the beginning `set(gen)` will work for any generator `gen`. – BrenBarn Aug 20 '14 at 18:49
  • I interpreted that as passing in the generator function instead of the iterator that is returned by calling the generator. But I see what you mean now! – tdelaney Aug 20 '14 at 18:50
  • @tdelaney: Technically the function is a "generator function" and its return value is the generator. But yes, the idea was that you would do `gen = generator_func()` and then call `set(gen)`. – BrenBarn Aug 20 '14 at 18:51
  • okay, curious, is there a way to do this if the generator `gen` returns tuples `item` and you only want one element of the tuple, `item[0]`? – ehacinom Aug 20 '14 at 18:56
  • @rebecca: You could do `set(item[0] for item in gen)`. – BrenBarn Aug 20 '14 at 18:57
  • okay, so the only way is a for loop. that's right, thank you! – ehacinom Aug 20 '14 at 18:59