В Python 3.x (и Python 2.7, когда он будет выпущен), вы можете использовать collection.Counter для этого:
>>> from collections import Counter
>>> list((Counter([2,2,1,1]) & Counter([1,3,3,1])).elements())
[1, 1]
Вот альтернативный вариант использования collection.defaultdict (доступно в Python 2.5 и более поздних версиях). У него есть приятное свойство: порядок результата является детерминированным (по сути, он соответствует порядку второго списка).
from collections import defaultdict
def list_intersection(list1, list2):
bag = defaultdict(int)
for elt in list1:
bag[elt] += 1
result = []
for elt in list2:
if elt in bag:
# remove elt from bag, making sure
# that bag counts are kept positive
if bag[elt] == 1:
del bag[elt]
else:
bag[elt] -= 1
result.append(elt)
return result
Для обоих этих решений количество вхождений любого данного элемента x
в выходном списке является минимумом числа вхождений x
в двух входных списках. Из вашего вопроса не ясно, хотите ли вы этого поведения.