Ответ 1
В Python 3.x(и Python 2.7, когда он был выпущен), вы можете использовать collections.Counter для этого:
>>> from collections import Counter
>>> list((Counter([2,2,1,1]) & Counter([1,3,3,1])).elements())
[1, 1]
Здесь альтернатива, использующая collections.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
в двух входных списках. Из вашего вопроса неясно, является ли это поведением, которое вы хотите.