Both solutions seem to be equivalent in that concerns the number of needed loop runs, but this two-step operation might require one less loop over list1.
The set&set solution, in contrary, might require one loop while transforming to a set and another one for the & operation.
python -m timeit -s "l1 = range(1, 10000); l2 = range(5000, 15000)"
"l3 = list(set(l1) & set(l2))"
100 loops, best of 3: 2.19 msec per loop
python -m timeit -s "l1 = range(1, 10000); l2 = range(5000, 15000)"
"s=set(l2); l3 = [i for i in l1 if i in s]"
100 loops, best of 3: 2.45 msec per loop
python -m timeit -s "l1 = range(1, 100000); l2 = range(50000, 150000)"
"l3 = list(set(l1) & set(l2))"
10 loops, best of 3: 28 msec per loop
python -m timeit -s "l1 = range(1, 100000); l2 = range(50000, 150000)"
"s=set(l2); l3 = [i for i in l1 if i in s]"
10 loops, best of 3: 28.1 msec per loop
So even with conversion back into list set&set is still marginally faster.
--
With best regards,
Daniel Kluev