IMO, set(l + [i ** 2 for i in l])
is a better solution. It is clearer than a nested generator comprehension.
And I have done a benchmark:
import timeit
l = list(range(5))
print(timeit.timeit("set(l + [_ ** 2 for _ in l])", 'from __main__ import ' + ', '.join(globals())))
print(timeit.timeit("{y for x in l for y in (x, x**2)}", 'from __main__ import ' + ', '.join(globals())))
output:
3.0309128219996637
3.1958301850008866
It shows set(l + [i ** 2 for i in l])
is a little faster. The reason I think is that nested generator comprehension need to create internal object (x, x**2)
for every loop, that makes it slow.
Update
import timeit
l = list(range(200000))
print(timeit.timeit("set(l + [_ ** 2 for _ in l])", 'from __main__ import ' + ', '.join(globals()), number=100))
print(timeit.timeit("{y for x in l for y in (x, x**2)}", 'from __main__ import ' + ', '.join(globals()), number=100))
output:
16.46792753900081
19.72252997099895