The last line performs an intersection between values of a and b in a list comprehension. Only pooly executed:
First I don't see why turning a into a set. Sampling a range of integers always provides distinct values. In that case it doesn't speed processing up, it just messes with the order (which is already random...).
Then, if i in b is inefficient (not noticeable if there are only a few values) because of the linear search (b being a list)
I'd rewrite it like this:
a = random.sample(range(1,30), 12)
b = set(random.sample(range(1,30), 16))
result = [i for i in a if i in b]
or even better using set intersection method.
result = set(random.sample(range(1,30), 12)).intersection(random.sample(range(1,30), 16))
In both rewrites, we create one set, to be able to use fast lookup / intersection with the other iterable.